Use a part of macro code independently - vba

I have one doubt!
I have a code for consolidation of 22 sheets in a workbook.
Now I want to prepare separate buttons for each sheet so that if the user wants they can consolidate only sheets required by them and not all 22 sheets.
I only know the way by creating 22 separate module having part of the codes related to each sheet. Is there any other concise way to do it which do not make me prepare 22 separate modules?
Code example:
sheets("AT").select
"whatever code that was required"
Sheets("DE").select
"whatever code that was required"
and so on....
Do let me know if question is not clear.

You only need a single module. When you click a button on a sheet it will be on the activesheet. Therefore you will only need to act on the activesheet and not every sheet in the workbook.
If I was doing the job I would create a userform with a List of worksheet names that the user can select and then the module will step through each selected worksheet name in the list and do whatever actions you need. A checkbox for whole workbook action would also be useful.
Make a new Userform with a commandbutton and also a list box called "myListBox" and ensure that the MultiSelect property is set to multi and not single then add the following code. This will step through each sheet in the workbook and adds the name to the listbox. Once you select a number of names and click the command button it will print the selected names to the Immediate window
Private Sub UserForm_Initialize()
Dim wks As Worksheet
For Each wks In ActiveWorkbook.Worksheets
Me.myListBox.AddItem wks.Name
Next
End Sub
Private Sub CommandButton1_Click()
For i = 0 To myListBox.ListCount - 1
If myListBox.Selected(i) Then
Debug.Print myListBox.List(i)
End If
Next i
End Sub

Related

VBA VeryHidden multiple tabs

I have done research and for whatever reason I cannot get this simple code to work correctly. Simply put, I am trying to xlveryhidden 5 tabs, but I receive run-time error 1004. If anything, it would be nice to change from the Sheet names to code names in case I change the tab names:
Sheet1 - Calculations
Sheet2 - LY Rates
Sheet3 - TY Rates
Sheet4 - Client Details
Sheet5 - Census
Sub VeryHiddenTabs()
Sheets(Array("Calculations", "LY Rates", "TY Rates", "Client Details", "Census")).Visible = xlVeryHidden
End Sub
I was able to use this to set my sheets to .Visible = False.
Sub HideMySheets()
Sheets(Array(Sheet1.Name, Sheet2.Name, Sheet3.Name, Sheet4.Name, Sheet5.Name)).Visible = False
End Sub
Unfortunately, it turns out you are not allowed to use this method to set them to .Visible = xlVeryHidden. Instead you have to do it on a per-sheet basis, using #Ibo's method.
Based on what you have provided it seems you are trying to make all of the sheets very hidden, you cannot do this. You MUST have at least one VISIBLE sheet in the workbook.
Additionally, to use VBA to make sheets very hidden not using the sheet names, you should then use the sheet indexes or sheets' code name. Sheets code name cannot be change using the interface so the code would work with whatever the sheet name is. To change the sheets' code name, go to VBE (ALT + F11), double click on the sheet you want and change the name, which is the first item in the properties window, if you don't see the properties window click F4. Let's say you change the code name of the sheet to mySht1 then you can do:
mySht1.Visible = xlVeryHidden
if you use the index of the sheets to change the visibility you can do this:
ThisWorkbook.Sheets(1).visible=xlVeryHidden
if you want to use this method, you need to always have one visible sheet so you have to create a sheet and then run this code:
Sub VeryHiddenTabs()
For i = 1 To ThisWorkbook.Worksheets.Count - 1
ThisWorkbook.Worksheets(i).Visible = xlVeryHidden
Next
End Sub
since you have already had the sheet you have mentioned, then Excel will make all of the very hidden. The above routine will keep the last created sheet visible and the rest very hidden.

Dialog box that selects a worksheet in Excel

I'm trying to build a macro that will duplicate a worksheet from one workbook into a worksheet in another workbook. Is there a way I can use VBA code to allow me to manually select which worksheet I shall be duplicating?
Right now the macro works, as long as I have the full worksheet name typed into the actual VBA code. Ideally, I'd like the macro to allow me to select the worksheet through a dialog box. I know you can just copy/paste the sheet or its contents, but the guys I'm working for don't want to do that, due to the size.
You can use Worksheets collection to populate the ListBox in a user form. This should get you started:
Code in the user form (!):
Private Sub UserForm_Initialize()
Dim v As Worksheet
For Each v In Worksheets
UserForm1.lstWorksheets.AddItem v.Name
Next
End Sub
Private Sub cmdSelectWorksheet_Click()
MsgBox "You selected " & lstWorksheets.Value
End Sub

VBA listbox select worksheet by index

I have a form with listbox which dynamically provides a list of the worksheets in the current workbook (code below). I wish to take the selected Sheet and refer to it in a formula later in the process. From hours of playing around I cannot seem to accomplish this. I believe I read somewhere that you cannot take the string back to the sub and use it to refer to to an object. So I thought maybe I can create two listboxes
for sheet name
for sheet index
that I could pass the index number to and maybe use that in my formula to lookup items from the correct sheet.
For the life of my I cannot seem to find a way to connect the two since the items will always be changing; the code will be ran on multiple workbooks by multiple operators so the layout will most likely change between users. I can easily add the second list box with index #'s but I have a block on how to associate the name which will have meaning to the user and the index which I can pass back to the sub. I realize the "On click" procedure for the list box to associate the two but with the dynamic nature of the fields I cannot come up with the logic to put that into code.
For N = 1 To ActiveWorkbook.Sheets.Count
With ListBox1
.AddItem ActiveWorkbook.Sheets(N).Name
End With
Next N
Try this out.
Declare a public variable above the code for the UserForm, making it available throughout your workbook from any module or code.
Public listChoice As String
Using your code to get the sheet names for the ListBox rowsource.
Private Sub UserForm_Activate()
For n = 1 To ActiveWorkbook.Sheets.count
With ListBox1
.AddItem ActiveWorkbook.Sheets(n).name
End With
Next n
End Sub
Including an update event for the ListBox
Private Sub ListBox1_AfterUpdate()
listChoice = ListBox1.Text
End Sub
I included a test just to demonstrate that the result is still retained. You don't need this, it demonstrates the results on the screenshot.
Private Sub cmdTestChoice_Click()
MsgBox ("The choice made on the ListBox was: " & listChoice)
End Sub
edit: To access that sheet later, you can call it using something like this:
Some examples of different ways to access a cell, using .Range, or .Cells, with numbers or letters.
Using lRow & lCol as Long to set row and column numbers.
Sheets(listChoice).Cells(lRow, lCol).Value = TextBox1.Value 'Set cell on sheet from TextBox
TextBox2.Value = Sheets(listChoice).Range("A2").Value 'Set TextBox From Cell on Sheet
'Set a cell on another sheet using the selected sheet as a source.
Sheets("AnotherSheet").Cells(lRow, "D") = Sheets(listChoice).Range("D2")

How to make a drop-down list for worksheets

I have a total of five sheets in a workbook. My task is to create a combo list button in the first sheet that will be able to point to the other four. If a user chooses one of the sheet names then the button will automatically activate the chosen sheet. It is unlikely that sheets will be deleted, though likely that sheets will be added.
I'm not even sure how to get the sheet names to show up on the combo list.
In order to make the combobox change the active sheet, I believe you'll need to use VBA (as I don't know how to do it using validation lists).
To do it, you'll have to:
1st - Add a combobox into your first sheet and properly name it (I called it cmbSheet). I suggest to use an ActiveX Combobox (in Excel 2007, under Developer tab).
2nd - Open VBA and add the below code into your workbook code. This code will populate the combobox with the sheet names every time the workbook is opened.
Private Sub Workbook_Open()
Dim oSheet As Excel.Worksheet
Dim oCmbBox As MSForms.ComboBox
Set oCmbBox = ActiveWorkbook.Sheets(1).cmbSheet
oCmbBox.Clear
For Each oSheet In ActiveWorkbook.Sheets
oCmbBox.AddItem oSheet.Name
Next oSheet
End Sub
3rd - Now, go to the code of your first sheet (where the combobox has been added) and add the code that will activate the sheet chosen in the combobox. The code is
Private Sub cmbSheet_Change()
ActiveWorkbook.Sheets(cmbSheet.Value).Activate
End Sub
Now, when the combobox value changes, the respective sheet is activated.
Let us know if something ins't clear and we'll help you out.

How to capture worksheet being added through Copy/Paste in Excel VBA

I am trying to capture worksheets being copied in to a workbook from another workbook.
Workbook_NewSheet event does not trigger when the sheets are copied from another workbook.
It is triggered only if the user manually inserts them through (Insert->Worksheet menu option), or when you add a new sheet through VBA as ThisWorkbook.Worksheets.Add.
What I am trying to capture is basically a Paste operation which is resulting in a new sheet.
This might be from any of the below user actions:
User copies an existing sheet by dragging it holding Control Key (which adds a new sheet)
User copies sheet/s from another workbook
user moved sheets from another workbook
or any of the below VBA code:
SourceWorkbook.Sheets(“SourceSheet”).Copy Before:=TargetWorkbook.worksheets(“SheetNameIn Target”) 'copy across workbook'
SourceWorkbook.Sheets(“SourceSheet”).Move Before:=TargetWorkbook.worksheets(“SheetNameIn Target”) 'move across workbook'
ThisWorkbook. Sheets(“SheetName”).Copy 'copy within workbook'
If you know any way of capturing this action/macro results within VBA that would be greatly helpful.
Please note that I do not want to avoid such an user action (so i do not want to secure the workbook) but I want to handle the pasted sheet programatically to verify the data, and if the similar sheet already exists then update the existing sheet rather than having same data in two sheets.
When a sheet is copied, its name will always end with "(2)", or at least ")". You could check on that like this
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If Sh.Name Like "*(2)" Then
Application.DisplayAlerts = False
Sh.Delete
Application.DisplayAlerts = True
End If
End Sub
The SheetActivate event will fire under all of those circumstances. Obviously it will fire under a lot of other circumstances too. This sounds like a royal pain, but you could maintain your own collection of worksheets and compare your collection to the ThisWorkbook.Sheets collection to see if something was added/deleted.
If you're trying to prevent it, you might consider protecting the workbook structure instead of doing it in code.
The way I have it implimented is
Private Sub Workbook_WindowActivate(ByVal Wn As Window)
ToggleMenuOptions False, 848, 889
End Sub
Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
ToggleMenuOptions True, 847, 848, 889
End Sub
Public Function ToggleMenuOptions(bToggle As Boolean, ParamArray ControlID() As Variant) As Boolean
'848 Move or Copy Sheet...
'889 Rename Sheet
'847 Delete Sheet
On Error GoTo lblError
Dim oControl As CommandBarControl, oControls As CommandBarControls, iControl As Integer
If IsMissing(ControlID) Then
ToggleMenuOptions = False
Exit Function
End If
For iControl = LBound(ControlID) To UBound(ControlID)
For Each oControl In Application.CommandBars.FindControls(ID:=ControlID(iControl))
oControl.Enabled = bToggle
Next
Next
ToggleMenuOptions = True
Exit Function
lblError:
If Err.Number Then
ToggleMenuOptions = False
Exit Function
End If
End Function
Private Sub Workbook_NewSheet(ByVal Sh As Object)
MsgBox "Please use Add New Project option in custom Toolbar to add new sheets!!", vbExclamation, "Not Supported"
Application.DisplayAlerts = False
Sh.Delete
Application.DisplayAlerts = True
End Sub
So my users wont be able to rename, add or delete sheets. This is working pretty well for now.
The only way I can think of doing this without maintaining a separate sheets collection is to maintain a static array of sheet names (or sheet codenames) and compare this to the actual sheets in the workbook each time the SheetActivate event fires to detect any additions. If you don't want to/can't keep the list in an array you could always use a hidden sheet to store the list. Whether this is any more or less of a pain than maintaining a separate collection is debatable :)
I am working on something similar but cannot block any of the user menu actions. I have sheets whose type are important - each sheet is either a Master or Slave - each Master sheet sums over the Slave sheets beneath it and I need to keep these formula clean.
Rather than maintain a list of sheets in an extra hidden sheet, I am defining 2 hidden names on each sheet recording the offset of the index of the Sheet to its linked Master sheet, and a reference to the linked Master sheet. So if my sheet is (say) +2 tabs from its Master sheet, then on Sheet activate/deactivate (not sure which of these is better to track at this stage) this offset will have changed if anything gets inserted, deleted or moved. This covers most or all of the events that would arise from moving or copying sheets.
If the sheet has been moved, I cycle through the workbook and calculate new Master/Slave index references for every sheet.
Will post code when I get this reasonably stable but it seems like a scheme that would work in a wide variety of circumstances.