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
Related
I have a workbook with a cover sheet and the remaining sheets are not visible. A tick-box displays tabs if ticked.
The cover sheet gets moved around in the book. I would like the cover sheet to always be in the first position.
Is there a way to do this?
Sub CheckBoxA1_Click()
Sheets("A").Visible = Not Sheets("A").Visible
End Sub
Sub CheckBox2_Click()
Sheets("B").Visible = Not Sheets("B").Visible
End Sub
The macro works well though the cover sheet extends up in different places well other sheets become visible. I would like it to be always in the first position. Is this possible?
Use the Workbook.Open event to move that particular sheet to the first position when the workbook is opened.
Add this code to the ThisWorkbook module and change Sheet1 to the codename of that sheet:
Private Sub Workbook_Open()
Sheet1.Move Before:=Me.Sheets(1)
End Sub
I have a userform which has multiple RefEdit controls. I need the user to select ranges from multiple sheets and the userform has to be complete before the rest of the code can run.
Issue: The activesheet is "Sheet1" when the userform is initiated. Each time I select a range on "Sheet2" and click into the next RefEdit the visible Excel sheet returns to "Sheet1". I'd like the sheet to remain on "Sheet2", since clicking between the sheets significantly increases the time it takes to select the data.
Because I need the userform to be completed before continuing with my code, using "vbModeless" doesn't appear to work.
I've tried to step through the userform events which appeared to be relevant but none were activated when I entered the RefEdit, selected the data, or left the RefEdit.
Thanks in advance for any help!
Edit: Using some input from the responses and doing some more research I think I've figured out the problem and a work around.
RefEdit events such as Change or Exit (I tried all of them I think) don't appear to trigger when a change occurs in the control. So I couldn't write code to manipulate the activesheet when I changed the control. A workaround found here: http://peltiertech.com/refedit-control-alternative/ uses a textbox and inputbox to simulate a RefEdit control and will actually trigger when changes are made! Code is below. To add other "RefEdit" controls you should repeat the code in the Userform_Initialize event for each control, then add another TextBox1_DropButtonClick and update TextBox1 to the name of the new control. In use when the control updates the workbook jumps to the previous activesheet and then returns the desired activesheet. Not as smooth as I'd like but much better than it was.
Code:
Private Sub CancelButton_Click()
Unload Me
End
End Sub
Private Sub OKButton_Click()
UserForm1.Hide
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
End
End Sub
Private Sub UserForm_Initialize()
Me.TextBox1.DropButtonStyle = fmDropButtonStyleReduce
Me.TextBox1.ShowDropButtonWhen = fmShowDropButtonWhenAlways
End Sub
Private Sub TextBox1_DropButtonClick()
Dim ASheet As String ' Active sheet
Me.Hide
'Use input box to allow user to select a range
On Error Resume Next
Me.TextBox1.Value = Application.InputBox("Select the range containing your data", _
"Select Chart Data", Me.TextBox1.Text, Me.Left + 2, _
Me.Top - 86, , , 0)
On Error GoTo 0
'Check if there is a sheet name - if the range selected is on the activesheet the output of the inputbox doesn't have a sheet name.
If InStr(1, Me.TextBox1.Value, "!", vbTextCompare) > 0 Then ' there is a sheet name
ASheet = Replace(Split(Me.TextBox1.Value, "!")(0), "=", "") ' extract sheet name
Else ' there is no sheet name
Me.TextBox1.Value = "=" & ActiveSheet.Name & "!" & Replace(Me.TextBox1.Value, "=", "") ' add active sheet name to inputbox output
ASheet = ActiveSheet.Name
End If
Worksheets(ASheet).Activate ' set the active sheet
Me.Show
End Sub
Have you tried something as simple as:
Sheets("Sheet2").Select
somewhere in the beginning of your form code ?
Since you haven't posted your code, it's hard to provide a good answer.
Hope this helps a little :)
This form module worked for me.
Private Sub CommandButton1_Click() 'Cancel Button
Unload Me
End Sub
Private Sub CommandButton2_Click() 'GO Button
Dim newSheet As Worksheet
abc = Split(RefEdit1.Value, "!")
cbn = abc(0)
Unload Me
Set newSheet = Worksheets(abc(0))
newSheet.Activate
End Sub
I have a workbook with about 50 sheets to be refreshed in a certain order (to avoid #rfr errors, since the sheets build off of one another).
The refresh is done via the EPM add in for Excel. I have activated the FPMXLclient functions and have attempted to write some code. I am very inexperienced with coding and logic. In the workbook the macro needs to start at the last tab, wait for the sheet to refresh, then move on to the next tab (and so on...). Below is an example of some of the VBA code I have written:
Dim refreshList
refreshList = Array("BS Analytic", "Balance Sheet")
'There are more than just the 2 in the array (~50)
Sub test_loop()
Dim I
For I = LBound(refreshList) To UBound(refreshList)
MsgBox refreshList(I)
Next I
End Sub
'Vba to refresh data
Dim client As New EPMAddInAutomation
Sub Refresh_Click()
client.Refresh
End Sub
Sub AFTER_REFRESH()
MsgBox "done"
End Sub
Other info: This involves BPC and SAP too.
Assuming that your addin refreshes the active sheet, something like this in your loop might work:
Dim Sh As Worksheet
Set Sh = WorkSheets(RefreshList(I))
Sh.Activate
Client.Refresh
Why not have each sheet number in the array refreshList and then use For each I in refreshList. That will then propagate the refreshList in the order for each update. If it is also moving from the last sheet backwards you could always do the following:
Sub Refresh_Click
Dim refreshList() As Integer
reDim refreshList(50)
for i = 0 to 49
refreshList(i) = 50 - i
next
For each I in refreshList
Sheets(I).EnableCalculation = false
Sheets(I).EnableCalculation = true
Next
MsgBox "Done"
End Sub
I'm somewhat newer to VBA, and this particular action seems like it may be out of my current scope of knowledge.
Is there a way to code VBA to have it actively select the same cell on all worksheets as the current cell selected? I have a model I've put together to allow my team to enter data simultaneously regarding product SKUs in Column A on Sheet1, but due to the large amount of information that we enter per item, I used multiple sheets
For example, if I have cell H4 selected on Sheet1, is it possible to have all other sheets active cell H4 upon switching to the other worksheets?
This is what I've come up with so far on a test workbook, but it does not seem to work:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Select Case LCase(Sh.Name)
Case Is = "sheet1", "sheet2", "sheet3"
If CurRow > 0 Then
With Application
.EnableEvents = False
.Goto Sh.Cells(CurRow, CurCol), Scroll:=True
Sh.Range(ActCellAddr).Select
.EnableEvents = True
End With
End If
End Select
End Sub
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
Select Case LCase(Sh.Name)
Case Is = "sheet1", "sheet2", "sheet3"
CurRow = ActiveWindow.ScrollRow
CurCol = ActiveWindow.ScrollColumn
ActCellAddr = ActiveCell.Address
End Select
End Sub
I've located this code below:
Excel VBA code to allow the user to choose the same cell on every sheet
But this requires the user actually enter the cell they'd like to have selected. I am looking for it to be automatic.
Any tips or suggestions? Any help is greatly appreciated.
You can post the following to every sheet in your workbook.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Set CurrWS = ActiveSheet
For Each WS In ThisWorkbook.Worksheets
WS.Activate
WS.Range(Target.Address).Select
Next
CurrWS.Activate
End Sub
Every time you select a cell, it will cycle through all the worksheets and select the same cell there. The downside to this is obvious: if you have too many sheets, it's going to be tedious. The other problem is that it's going to cycle through everything. So it might mess up some other sheets if you're going to use this for data entry.
Otherwise, if it's just selecting the cell, then this is harmless though the flicker can be noticeable at times, based on how many sheets you have.
Not as elegant as one would want, but it works. Good luck and let us know if this helps.
Worth noting there is a workbook-level event handler which handles the same event, so you only need to add the code once to the ThisWorkbook code module:
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, _
ByVal Target As Range)
Sh represents the ActiveSheet.
Probably also worth disabling events while you're selecting the ranges on the other sheets, or that will re-trigger your event handler (don't forget to turn event handling back on before exiting your code!)
This approach will test for hidden sheets. It selects all non-hidden sheets, selects the target cell then returns to the original sheet. It works pretty fast even if you have many many tabs.
targetcell = ActiveCell.Address
OriginSheet = ActiveSheet.Name
Dim ws As Worksheet
For Each ws In Sheets
If ws.Visible = True Then ws.Select (False)
Next ws
range(targetcell).Select
Sheets(OriginSheet).Select
My problem are command buttons that fail to respond when I've selected multiple sheets in a workbook. The workbook I'm testing here is meant only to study and troubleshoot this problem, which I originally found in a much more complicated workbook.
My workbook has a total of 5 worksheets. There are four ActiveX command buttons on sheet1. These four buttons launches code to either select several worksheets together or just sheet1.
After selecting multiple sheet together, only the last button clicked actually can be clicked again, the rest of the buttons on the sheet1 don't respond anymore, like they're disabled or something. Once I manually deselect the sheets so that just sheet1 is selected, the controls start working normally.
Weird.. I think it must be some sort of bug in Excel. I also can replicate the problem if I manually select multiple worksheets rather than let the code do it.
Some of my findings so far...
It doesn't seem to matter how many sheets I select so long as its two or more.
VBA code selection or manual SHIFT-CLICK doesn't matter.
The last button activate still runs once the other buttons gets locked up.
I only get this with Excel 2010, Excel 2007 didn't have this problem.
I've replicated the problem in a isolated workbook, so I don't think this is corruption issue.
The 4 command buttons execute the functions shown below. Each button marks adjacent cells if the code runs. I put a 1 second delay to verify clicking a button twice in a row was working.
CMD 1: Select sheet1 only
CMD 2: Select sheet1 only
CMD 3: Select sheet1 and sheet2
CMD 4: Select sheet1 through sheet4 via sub routine in module1
Here is my code attached to sheet1....
Option Explicit
Private Sub CommandButton1_Click()
Call MarkCmdsAsInactive
Me.Select
Call WaitSeconds(1)
Range("E6").Value = "CMD 1 Works"
End Sub
Private Sub CommandButton2_Click()
Call MarkCmdsAsInactive
Me.Select
Call WaitSeconds(1)
Range("E10").Value = "CMD 2 Works"
End Sub
Private Sub CommandButton3_Click()
Call MarkCmdsAsInactive
Sheets(Array("Sheet1", "Sheet2")).Select
Call WaitSeconds(1)
Range("E14").Value = "CMD 3 Works"
End Sub
Private Sub CommandButton4_Click()
Call MarkCmdsAsInactive
Call SelectSomeSheets
Call WaitSeconds(1)
Range("E18").Value = "CMD 4 Works"
End Sub
Private Sub MarkCmdsAsInactive()
Range("E6").Value = "Inactive"
Range("E10").Value = "Inactive"
Range("E14").Value = "Inactive"
Range("E18").Value = "Inactive"
End Sub
Private Sub WaitSeconds(waitInSeconds As Variant)
Dim newHour As Variant
Dim newMinute As Variant
Dim newSecond As Variant
Dim waitTime As Variant
newHour = Hour(Now())
newMinute = Minute(Now())
newSecond = Second(Now()) + waitInSeconds
waitTime = TimeSerial(newHour, newMinute, newSecond)
Application.Wait waitTime
End Sub
In module1 I have...
Option Explicit
Sub SelectSomeSheets()
Sheets(Array("Sheet1", "Sheet2", "Sheet3", "Sheet4")).Select
End Sub
Update 2012-10-09
Here is a simple way to replicate this bug in Excel 2010...
Place 4 command buttons on sheet1.
Copy the code below to sheet1.
Put breakpoints on each of the "End Sub" statements.
Try clicking the buttons with just sheet1 selected. All buttons launch routines.
SHIFT-CLICK to select a group of sheets.
Try buttons again with the sheet group selected. Only the last used button works.
Private Sub CommandButton1_Click()
End Sub
Private Sub CommandButton2_Click()
End Sub
Private Sub CommandButton3_Click()
End Sub
Private Sub CommandButton4_Click()
End Sub
I guess it has to do with the "scope" of the ActiveX buttons (i.e. scope is sheet1 and not sheet1+sheet2+...). It seems that the selection of multiple sheets deactivates command buttons in sheet 1, even if sheet 1 remains the "active" sheet. because the ActiveX components are private to sheet1.
As a workaround, I moved your Sub CommandButtonX_Click to Module 1, removed the Private keyword, created a custom ribbon MyTools with the 4 Sub's as selectable elements. This way I moved the visibility of the sub's from sheet level to application level and all works.
Of course I had also to change Me.Select into Sheets("Sheet1").Select (allthough I hate hard codings like this ....)
Hope that helps ...