How to get the last sheet created in excel ?
I used GetSheets.Last, and it work but he found me the last sheet what it is in queued, it’s right, but if my last sheet doesn’t follow the order of the queued for example it is in the middle, the function GetSheets.Last doesn’t work.
Exist some function where the robot can found or understand which sheet has been created for last ?
Thank you very much
best regards
On the workbook, there is a NewSheet event that can help you get the sheet at the very moment it is created. The complete signature is Private Sub Workbook_NewSheet(ByVal Sh As Object)
Once you close/reopen the workbook, the information will be lost though, so you need to save the sheet's name in some cell for future use.
It can be:
Private Sub Workbook_NewSheet(ByVal Sh As Object)
Worksheets(1).Cells(1, 1).Value = Sh.Name
End Sub
Related
I have simple code which is moving worksheet "Data" to after activated worksheet.
Sub Workbook_SheetActivate(ByVal Sh As Object)
Worksheets("Data").Move After:=Worksheets(Sh.Name)
Worksheets(Sh.Name).Activate
End Sub
I am using
Worksheets(Sh.Name).Activate
because without this line worksheet "Data" remains selected after the move which is not the intention.
The problem I have is when this code is run it takes about 2-3 seconds for excel to think about it before seeing result.
I don't understand why. Without chaining these 2 operations together it takes milliseconds. Could someone please explain how to improve this and why is this happening?
This should be quicker:
Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim nam As String
nam = Sh.Name
Application.EnableEvents = False
Worksheets("Data").Move After:=Worksheets(nam)
Worksheets(nam).Activate
Application.EnableEvents = True
End Sub
This happens because of recursive calling: when you use .Activate, then your Sub Workbook_SheetActivate is called again and you're stuck in an endless loop.
If you simply want to deselect the data range, you can use Cells(1,1).Select and you can directly use Sh instead of using Worksheets(Sh.Name), since they're equivalent.
So your final code would be:
Sub Workbook_SheetActivate(ByVal Sh As Object)
Worksheets("Data").Move After:=Sh
Cells(1,1).Select
End Sub
Hope this helps.
Thanks for your input guys. Turning off/on events helped to get out of the loop.
Application.EnableEvents = False
Worksheets("Data").Move After:=Sh
sh.Activate
Application.EnableEvents = True
I should have probably explained what the code was being used for in my question.
The user had 50+ Worksheets in the Workbook (please don't ask me why :)). They had one in particular ("Data") they wanted to be able to click in and out whilst working with other worksheets. So this code was simply causing the Worksheet "Data" to "follow them"
The line:
sh.Activate
Was used to get back to the Worksheet they have just clicked on as otherwise they were getting stuck on "Data" Worksheet.
I have been searching for a solution for the following problem for days now, but I just can't figure it out.
I have a Excel Workbook with multible sheets. Some sheets contain code and there are also multible modules with code. Keep in mind, that the sheet names, postition and quantity can be changed by the end user.
In the sheet with the code.name "Tabelle 1" I have the following code:
Sub Reset_ToggleButton1()
If ToggleButton1.Value = True Then
ToggleButton1.Value = False
End If
End Sub
As far as I found out, I can only activate ToggleButtons with code in their respective sheet. If this is not true, this might be a possible solution to my problem.
Further I would like to call the sub Reset_ToggleButton1() from a modul. But, as there can be multible copies of the sheet with the toggle button and the respective code, I would like to referece the sub in the active sheet.
The following code worked, but only for the sheet named.
Sub test()
Application.Run "Tabelle1.Reset_ToggleButton1"
End Sub
I think what I need is to replace the "Tabelle1" with the code name of the active worksheet. I know, I can get the Code.Name with of the active worksheet with the following code:
Dim SheetCode As String
SheetCode = ActiveSheet.CodeName
But I don't know how to insert it into the Sub test() from above.
Your help is very much appreciated!
Best wishes
Anne
you can use
ActiveSheet.Reset_ToggleButton1
or
Worksheets("Tabelle1").Reset_ToggleButton1
to run it.
Worthy of mention, you can specify worksheet:
Sub Test(WS As Worksheet)
WS.Reset_ToggleButton1
End Sub
I have 50 datasheets in the project, and nobody remembers to run the save macro when going to another sheet. The bright idea is to use a private sub Worksheet_Deactivate to do the necessary calculations when they select another worksheet. In addition to the 50 datasheets, there are two more worksheets in the workbook for which the calculation must not run. It would be nice if the sub could be put in "Worksheets" rather than replicated 50 times in individual worksheets, but the two other worksheets need to be excluded from processing.
Problem is, the sub defaults to the deactivating worksheet (such as an unqualified "Range.Value =" in the macro code), but the active worksheet is now the worksheet being navigated TO. So any ActiveXXXXX statement directs to the wrong worksheet. Worksheet.Name is disallowed.
Datasheets are numbered 1 to 50. What is needed is a statement early in the deactivate sub similar to
If DeactivatingWorksheet(X) = "BasicInfo" Or "Constants" Then GoTo EndSub
where X is the value of the deactivating worksheet. Of course, X is known only to Excel at the moment of processing.
I can't seem to figure out how to refer to the deactivating worksheet in the macro's IF statement. Any ideas?
Use Workbook_SheetDeactivate(ByVal sh as Object) instead of Worksheet_Deactivate(). The Workbook-level event supplies the name of the sheet being departed, even though in both cases the ActiveSheet has already changed when when event fires. Use sh just like a worksheet variable - sh.Name, sh.ProtectionMode, etc.
Now you don't need 50 subs; just one. Another thing that this allows is, you can "abort" the change to the now ActiveSheet by sh.Activate to the old one (but turn off events or you'll have a lovely infinite loop).
Me also gives the old sheetname and works for the worksheet event, if you still want to go that way. Me is the old one, ActiveSheet is the new one.
If you are using Worksheet_Deactivate and this calls a subroutine in a seperate module, you can pass the name of the deactivating worksheet to the subroutine.
For instance, if your subroutine is something like:
Sub test()
ActiveSheet.Range("whatever") = "something"
ThisWorkbook.Save
End Sub
And you call it from the worksheet like:
Private Sub Worksheet_Deactivate()
Module1.test()
End Sub
You can add a parameter to the subroutine to take the worksheet name, and add a test:
Sub test(worksheetname as string)
If worksheetname <> "dontsavethistab" then
ActiveSheet.Range("whatever") = "something"
'or... you could also do:
Sheets(worksheetName).Range("Whatever") = "something"
ThisWorkbook.Save
End If
End Sub
And call it from your Worksheet_Deactivate event like:
Private Sub Worksheet_Deactivate()
Module1.test (Me.Name)
End Sub
If you wanted to get a little cleaner, instead of the worksheet name you could pass the worksheet object:
Private Sub Worksheet_Deactivate()
Module1.test(Me)
End Sub
Sub test(ws as worksheet)
If ws.name <> "dontsavethistab" then
ws.Range("Whatever") = "something"
ThisWorkbook.Save
End If
End Sub
This way you have the entire worksheet object to do with as you please in your subroutine.
I have 5 sheets in the Excel file, the sheet names are Main, Production, Outflow, Inflow, Options.
Is there a way I can set up a formula in the Options sheet to reference the name of the sheet I'm currently viewing?
So if I'm viewing the Production sheet it'll put Production in A1 of the Option sheet, then if I click to view the Outflow sheet it'll change the A1 in the Option sheet to show Outflow.
Tried searching but couldn't find anything like this anywhere. Thanks for any help.
Assuming that you don't want anything to happen if Options is selected, the following subroutine should work:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If Sh.Name <> "Options" Then
ThisWorkbook.Sheets("Options").Range("A1") = Sh.Name
End If
End Sub
If you want to still show Options when Options sheet is selected, just remove the IF-THEN block. :)
Make sure to copy and paste the above to the ThisWorkbook code area.
Let us know if this helps.
In the ThiwWorkbook module add
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Sheets("Options").[a1] = Sh.Name
End Sub
Which will put the current sheet name in cell A1 of a sheet called Options
I have an Excel workbook in which I have tabs representing dates along with sum in each tab. Although I can take the sum of all these in the final sheet, I want a formula/macro to get the sum in the total named sheet, when a new spreadsheet is being added.
Note:- the cell in all would remain the same (E56)
I do not understand what you are attempting. Until the user has placed information in the new sheet that results in a value in E56, I see little point to adding the value of NewSheet!E56 to the total sheet.
However I suspect you need to use events. Below are a number of event routines which must be placed in the Microsoft Excel Object ThisWorkbook for the workbook. These just output to the Immediate window so you can see when they are fired. Note: several can be fired for one user event. For example, creating a new worksheet, triggers: "Create for new sheet", "Deactivate for old sheet" and "Activate for new sheet".
Do not forget to include
Application.EnableEvents = False
Application.EnableEvents = True
around any statement within one of these routine that will trigger an event.
Perhaps you need to use SheetDeactivate. When the users leaves a sheet, check for a value in E56. If present, check for its inclusion in the totals sheet. Have a play. Do what your users do. Add to these routines to investigate further. Good luck.
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Debug.Print "Workbook_SheetActivate " & Sh.Name
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call MsgBox("Workbook_BeforeClose", vbOKOnly)
End Sub
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Source As Range)
Debug.Print "Workbook_SheetChange " & Sh.Name & " " & Source.Address
End Sub
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
Debug.Print "Workbook_SheetDeactivate " & Sh.Name
End Sub
Private Sub Workbook_NewSheet(ByVal Sh As Object)
Debug.Print "Workbook_NewSheet " & Sh.Name
End Sub
Sub Workbook_Open()
Debug.Print "Workbook_Open"
End Sub
Extra section in response to clarification of requirement
The code below recalculates the grand total of cell E56 for all worksheets except TOTAL and stores the result in worksheet TOTAL every time the workbook is opened and every time the user changes the current worksheet.
It is difficult to get consistent timings with Excel but according to my experimentation you would need between 500 and 1,000 worksheets before the user would notice a delay switching worksheets because of this recalculation.
I am not sure if you know how to install this code so here are brief instructions. Ask if they are too brief.
Open the relevant workbook.
Click Alt+F11. The VBA editor displays. Down the left you should see the Project Explorer. Click Ctrl+R if you do not. The Project Explorer display will look something like:
.
VBAProject (Xxxxxxxx.xls)
Microsoft Excel Objects
Sheet1 (Xxxxxxxxx)
Sheet10 (Xxxxxxxxx)
Sheet11 (Xxxxxxx)
:
ThisWorkbook
Click ThisWorkbook. The top right of the screen with turn white.
Copy the code below into that white area.
No further action is required. The macros Workbook_Open() and Workbook_SheetDeactivate() execute automatically when appropriate.
Good luck.
Option Explicit
Sub CalcAndSaveGrandTotal()
Dim InxWksht As Long
Dim TotalGrand As Double
TotalGrand = 0#
For InxWksht = 1 To Worksheets.Count
If Not UCase(Worksheets(InxWksht).Name) = "TOTAL" Then
' This worksheet is not the totals worksheet
If IsNumeric(Worksheets(InxWksht).Range("E56").Value) Then '###
TotalGrand = TotalGrand + Worksheets(InxWksht).Range("E56").Value
End If '###
End If
Next
'Write grand total to worksheet TOTAL
' ##### Change the address of the destination cell as required
Worksheets("TOTAL").Range("D6").Value = TotalGrand
End Sub
Sub Workbook_Open()
' The workbook has just been opened.
Call CalcAndSaveGrandTotal
End Sub
Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
' The user has selected a new worksheet or has created a new worksheet.
Call CalcAndSaveGrandTotal
End Sub
I know this is the programming forum, but this particular "need" seems to be solvable without all the plumbing.
I like the old hidden FIRST and LAST sheets trick.
Create a sheet called First
Create a sheet called Last
Place your current data sheets between these two sheets.
Hide the sheets First and Last
Now you can use 3D formulas to sum cells from all these sheets, like so:
=SUM(First:Last!E56)
Now just add sheets to your workbook AFTER the last visible data sheet and Excel will still slip it in ahead of the hidden LAST sheet, so your formula just expands itself that way