Calling Value From another macro - excel

I have a userform which opens one of a list of worksheets. I want to create a macro that recognises the last sheet opened by the userform and then runs data validation based on data types in the sheet.
How can I reference the sheet opened so that it can be called later my the validation macro?
All help gratefully accepted!

You need to "remember" it in a Public variable.
In a Standard Module, near the top of that module, include:
Public LastSheet As Worksheet
and in the UserForm, code like:
Sub WithinUserForm()
Dim x As String
x = Application.InputBox(Prompt:="pick a worksheet", Type:=2)
Sheets(x).Select
Set LastSheet = ActiveSheet
End Sub
Finally within the DV macro:
Sub MacroForDV()
LastSheet.Select
End Sub

Related

Workbook event not working in new workbooks

I'm totally new to Excel_vba, I'm trying to make kind of simple macros in excel.
I'm intending to make a macro: If active sheet is the first sheet in the workbook, move to last activated sheet. Else if, move to the first sheet in the workbook.
I googled and I added the code below to 'thisworkbook' module in addin (.xlam).
Private Sub Workbook_SheetdeActivate(ByVal Sh As Object)
Set LstSht = Sh
End Sub
In next, I create general module in addin(.xlam), added the code below.
Global LstSht As Worksheet
Sub GoToLast()
LstSht.Activate
End Sub
Private Sub Sht_tab()
If ActiveSheet.Index = 1 Then
Call GoToLast
ElseIf ActiveSheet.Index <> 1 Then
ActiveWorkbook.Sheets(1).Activate
End If
End Sub
The problem is, even though I move to any other sheet in workbook, sheetdeactivate event is not working, so LstSht object is not defined.
The event: sheetdeactivate only works in specific workbook? I want to assign a shorcut to this macro and use it in other workbooks, but I can't make it run.
Thank you for all in advance.

Create Excel sheet with worksheet_change code [duplicate]

This question already has an answer here:
Excel vba add code to sheet module programmatically
(1 answer)
Closed last year.
I have code that creates a worksheet and the worksheet contains a table.
I then programmatically add an advanced filter to the table in the created worksheet.
This works fine, but the advanced filter does not refresh on change of the worksheet: A known issue.
The standard solution is to put code behind the worksheet_change event so the filter is refreshed when the worksheet changes. This also works fine when I add this code manually.
But when I create a sheet I want to automatically create the code for the new sheets worksheet_change event. I don't know how to programmatically specify code for my new sheet in the worksheet_change event.
Is this possible? Or is there another way to accomplish this?
Maybe look at using this instead. It'll fire for all sheet changes and allows your code to work centrally ...
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
End Sub
You can create a class module with the event and hook that to your worksheets. So you can add a hidden sheet with all workbook names that you want to add that event to.
So if you programmatically add a new sheet you just need to add its name to that list.
So first add a sheet named MyClassSheets (you can make it hidden so no user sees it). And add some sheet names there:
So this means we want to run your worksheet_change event in Sheet2 and Sheet3 only.
Then we add a class module MyWsClass:
Option Explicit
Public WithEvents Ws As Worksheet
Private Sub Ws_Change(ByVal Target As Range)
MsgBox Target.Address(False, False) & " changed."
End Sub
This is the event we want to run. It just shows a message box which cell was changed. You need to adjust that to your wishes.
Finally we need to hook those events to the worksheets. So we add a normal module (non-class module) HookWsEvents:
Option Explicit
Dim MyWorksheets() As New MyWsClass
Public Sub HookEvents()
' get list of worksheets we want to add the class
With ThisWorkbook.Worksheets("MyClassSheets")
Dim MyClassSheets() As Variant
MyClassSheets = .Range("A1", .Cells(.Rows.Count, "A").End(xlUp)).Value
End With
ReDim MyWorksheets(UBound(MyClassSheets) - 1)
Dim i As Long
' add class to those worksheets
Dim Ws As Variant
For Each Ws In MyClassSheets
Set MyWorksheets(i).Ws = ThisWorkbook.Worksheets(CStr(Ws))
i = i + 1
Next Ws
End Sub
So now we just need to make sure that the procedure HookEvents is called everytime the workbook opens. So we add the following into ThisWorkbook:
Option Explicit
Private Sub Workbook_Open()
HookEvents
End Sub
After running HookEvents the event runs in every sheet that is listed in MyClassSheets.
If you now add a new worksheet that you want to add the event to, you just need to add it to the list in MyClassSheets and run HookEvents again. Therefore we can add a small helper procedure to our HookWsEvents module:
Public Sub AddWsToList(Ws As Worksheet)
With ThisWorkbook.Worksheets("MyClassSheets")
' add the worksheet name of Ws to the list in MyClassSheets
.Cells(.Rows.Count, "A").End(xlUp).Offset(RowOffset:=1).Value = Ws.Name
End With
End Sub
So now we can use the following code
' add a new worksheet as last worksheet
Dim NewWs As Worksheet
Set NewWs = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
' give it a name
NewWs.Name = "Sheet5"
' add it to the list of MyClassSheets
AddWsToList NewWs
' hook events to all sheets
HookEvents
to add a new worksheet and add the event to it.
You may want to add some error checking if a worksheet in the list of MyClassSheets does not exist anymore (was deleted) so your code does not thorw an unhandled exception in this case. I left this out to have the above explanation more clear.
If all your sheets have someting common in their name you don't need to maintain that MyClassSheets list. So for example if all the sheets you want to add the event to start with XYZ_ you just need to loop over all sheets in the HookEvents procedure and check if they start with XYZ_ to add them to the MyWorksheets array then. Resizing that array may be a bit more complicated then.

Unprotect sheet in MS Excel for ActiveX controls

I implemented smart dropdown (using Active X controls) in my sheet, so it is protected.
This functionality is not able to work because of protection.
When I right click on the sheet and Unprotect it, providing the password, it works.
I do not want the user to do this manually. I want that when user opens the sheet the sheet should get unprotected using VBA code.
The entire cells in the sheet are Locked (Format cells-> Protection -> Locked marked).
I cannot untick the Locked mark, as there are some validations which gets failed and not allow me to upload such template.
Below is an example as I cannot share the application code.
VBA code:
In sheet1-> name of sheet is "tab0"
Private Sub Worksheet_BeforeDoubleClick _
(ByVal Target As Range, _
Cancel As Boolean)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
ws.Unprotect Password:="xxx"
Inside ThisWorkbook I have this
Private Sub Workbook_Open()
ThisWorkbook.UnProtect Password = "password"
End Sub
A late input to this question:
I've been experiencing similar problems with Unprotecting sheets, and ended up doing aa fair bit of testing to find what works and what doesn't (always!).
The problem appears to be when assigning the sheet to an object and using the object's dot notation to unprotect e,g.:
'Setting the worksheet (globally) in sub Main()
Public goXsTT As Worksheet
Set goXsTT = goXbWb.Sheets(2)
'Somewhere else in the code
goXsTT.Unprotect
'This ***may*** fail, whereas:
Sheets(2).Unprotect
'Works!
No idea why this is the case - just pointing out that it's a workaround if you're stumped, as I was. Hope it helps. DG

How to copy the code used in one sheet/tab in a workbook to create a report in another sheet/tab within the same workbook

Let's say, there is a report that has already been created in a sheet in a work book using macros. I want to create another report within the same workbook in another sheet(tab) with the exact same code in VBA which was used to create the report that has already been created. How do i copy and make those codes work in a different sheet to create a similar report?
Any code in the Worksheet itself should use Me to refer to itself - this way, it will work when copied/duplicated
Any other code should take the Worksheet to act on as a Argument, or as Module Level Object:
Option Explicit
Sub CreateReport(TargetSheet As Worksheet)
TargetSheet.Cells(1,1).Value = "Hello"
End Sub
or
Option Explicit
Public TargetSheet AS Worksheet
Sub CreateReport()
If TargetSheet Is Nothing Then Exit Sub 'In case the object has not been set
TargetSheet.Cells(1,1).Value = "Hello"
End Sub
Then you can duplicate a "master" template sheet, and run the macros to target it

Adding list of open workbooks to combo-box and related worksheets to a list-box (VBA Excel)

I am working on a userform where a combobox gives user the names of every excel workbook that are already opened at that moment.
I want to put the names of all worksheets taking place in the workbook that is selected in the combobox on a listbox and I want it to be dynamic -that is, as the user selects another workbook from the combobox, the names (of the worksheets) appearing in the listbox should be automatically changing.
However, I can't figure out how I can access to the inventory of the combobox and make the desired additions. Any help/comment is appreciated. Thank you.
You can use the following functions
This one is for the UserForm, when it initializes it will fill in the combobox with all open sheets
Private Sub UserForm_Initialize()
Dim i As Long
For i = 1 To Workbooks.Count
ComboBox1.AddItem (Workbooks(i).Name)
Next
End Sub
This is about the Combobox itself, whenever you select some workbook from the combobox this function will be called and it is filling the list box with the sheets of that workbook.
Private Sub ComboBox1_Change()
Dim selected_wb As Workbook
Set selected_wb = Workbooks(ComboBox1.Text)
ListBox1.Clear
For Each ws In selected_wb.Worksheets
ListBox1.AddItem ws.Name
Next ws
End Sub
This function is called when you click the sheet name from the listbox, it will select the sheet and will close the user form
Private Sub ListBox1_Click()
Dim selected_wb As Workbook
Dim selected_ws As Worksheet
Set selected_wb = Workbooks(ComboBox1.Text)
Set selected_ws = selected_wb.Sheets(ListBox1.Text)
selected_ws.Activate
UserForm1.Hide
End Sub

Resources