I have a problem with a VBA script. I guess the solution is simple, but I just wasnt able to figure it out....
So basically, I have a workbook that contains many worksheets. Each worksheet contains the exact same format of a table (same number of rows and columns). What I wanted to do was to create a new worksheet and in that worksheet, have averages of all those values.
So for example in cell B2 I want to have average of cells B2 from all the other worksheets. I therefore created a macro that does this, this is not a problem, the problem is however, that in that macro, all sheets are referred to by their names and since I have many of these workbooks with differently named sheets, this would not work. I therefore tried to change the name of the first sheet to actual reference of sheet - i.e. Sheet(1) and the last one as Sheet(x) - where x is the number of sheets I calculated previously. Unfortunately the code doesnt work, could anyone please suggest to me how to modify this so that it works properly? I am only copying the problematic part of the code:
x = Sheets.Count
Sheets.Add After:=Sheets(x)
Range("B2").Select
ActiveCell.FormulaR1C1 = "=AVERAGE(Sheets(1):Sheets(x)!RC)"
Try this. You are not offseting your sheet names (in fact, you're not even using the sheet names. In the context of a formula, Sheets(1) is meaningless. You need to use Sheets(1).Name and offset it appropriately:
"=AVERAGE('" & Sheets(1).Name & ":" & Sheets(x).Name & "'!RC)"
Related
I have an Excel-file which contains a least two sheets: a summary sheet (Sheet1), a template sheet (Sheet2) and a variable amount of sheets. I have a small macro which copies Sheet2 to the very end of the sheets and renames the new sheet to whatever I type into an input box.
I also want the macro to make A1 in Sheet1 as a reference to whatever the value is in A1 of the new sheet ("Last Sheet"). But my problem is to define a variable that equals the name of the new sheet.
I've tried to use Sheets(Sheets.Count) with no luck.
Sheets("Sheet1").Range("A1").Formula = "='Sheets(Sheets.Count)'!A1"
I expect the formula ='NameOfTheLastSheet'!A1 to be present in A1 in Sheet1.
Instead Excel wants me to open a file to update the value of Sheet(Sheets.Count).
(I'm a noob to VBA but I don't mind looking into certain areas, if I'm pointed in the right direction.)
You are close, just some issues with syntax.
Sheets("Sheet1").Range("A1").Formula = "='"& Sheets(Sheets.Count).Name & "'!A1"
Because Sheets(Sheets.Count).Name is vba syntax to return the name of the worksheet, it needs to be concatenated outside the rest of the actual formula string.
This question already has answers here:
Excel VBA Sum from Multiple Sheets
(3 answers)
Closed 3 years ago.
I need to sum values across multiple sheets. The sheets will always have different names as they are set by the date.
I have a summary sheet as the first sheet in my workbook.
From a field in my summary sheet, I'd like to read through each sheet and if the value of the fields match it adds the values together.
For example, pseudo code would be, Go through each worksheet and if SummarySheet.Range("A24").value is in range(G1:G200) sum up the corresponding cell in range("H1:H200").
I've tried sum if and sum product.
I've tried the below code. Which bombed!
For Each Cell In Range("A24:A224")
For Each ws In ThisWorkbook.Worksheets
For Each i In ThisWorkbook.ActiveSheet.Range("G2:H200")
If Cell.Value = i.Value Then
ActiveCell.Offset(0, 1).Select
Cell.Value = Cell.Value + i.Value
End If
Next i
Next ws
Next Cell
Your code is referencing "ActiveSheet" and "ActiveCell" but it's not activating anything within the loop.
It is very difficult to guess what your code is trying to do. This answer is more about good coding practice than specific recommendations. My hope is this will allow you to correct your own code.
ActiveCell.Offset(0, 1).Select serves no purpose. The ActiveCell is the cell containing the cursor. You do not position the cursor at the beginning of the routine to a first cell and you neither read from nor write to the ActiveCell during the rest of the macro.
For Each ws In ThisWorkbook.Worksheets serves no purpose since you do not use ws. In For Each i In ThisWorkbook.ActiveSheet.Range("G2:H200") did you mean to write For Each i In ws.Range("G2:H200")? I cannot see anywhere else you might have meant to use ws.
Each Cell In Range("A24:A224") references the ActiveSheet. This is whatever worksheet happens to be active when the macro was started. My guess is that Range("A24:A224") is in the summary worksheet. If the user happens to be looking at another worksheet when they start the macro, that other worksheet is the ActiveSheet and not the summary worksheet. I assume you want to accumulate totals in the summary worksheet. If the wrong worksheet is active when the macro is started, that worksheet will be corrupted beyond recovery. UnDo cannot undo what a macro has done so you will have to revert to the previous copy of the workbook. I hope you create a new copy of the workbook before trying experimental macros so you can revert to an undamaged version. You need something like:
Dim WshtSumm As Worksheet
Set WshtSumm = Worksheets("Summary")
For Each Cell In WshtSumm.Range("A24:A224")
: : : : : : :
Next
In my opinion, you should not use names like Cell because it is too similar to the reserved word Cells. You should not use names like i because such names are meaningless. Perhaps it does not matter in such a small macro but, as your macros get bigger, meaningful names will be a real help when you or someone else looks at this macro in six or twelve months. Few macros last unchanged for ever; they are updated every few months to address changing requirements. I do not know what Cell and i represent but perhaps CellSumm and CellData would be better names.
Consider ThisWorkbook.Worksheets and Range("A24:A224"). I have just told you that you should have identified which worksheet holds Range("A24:A224"). This was because your workbook holds several worksheets any of which could be active. If you have a workbook that has only one worksheet, Range("A24:A224") might be OK. Personally, I avoid unqualified ranges because it is so easy to add a new worksheet. However, is it likely that you will have two workbooks or more workbooks open? Yes, it is possible to run a macro in one workbook from another workbook but is this likely? ThisWorkbook identifies the workbook holding the macro. If you are concerned that the wrong workbook will be active, you are absolutely correct to specify which collection of worksheets you wish to access because each workbook has its own collection. However, Worksheets on its own will normally be sufficient. This is something you need to think about, particularly as your macros get more complicated: do I need to qualify this range or worksheet or anything of which you might have more than one?
Consider:
For Each ws In ThisWorkbook.Worksheets
For Each i In ws.Range("G2:H200")
I have not qualified ws because a worksheet has a property Parent which identifies its workbook. You qualified ws when you created it.
One of the worksheets in ThisWorkbook.Worksheets will be the summary worksheet. Do you want to examine cells in the summary worksheet? I assume not. You need something like:
Dim WshtSumm As Worksheet
Dim WshtOther As Worksheet
Set WshtSumm = Worksheets("Summary")
For Each WshtOther In Worksheets
If WshtOther.Name <> WshtSumm.Name Then
: : : : : : :
End If
Next
This code only examines worksheets whose name does not match the summary worksheet's name. Whenever you look through an entire collection of something, you need to ask yourself: do I really want to look at everyone?
Consider:
If Cell.Value = i.Value Then
ActiveCell.Offset(0, 1).Select
Cell.Value = Cell.Value + i.Value
End If
Where you have written ActiveCell, I suspect you meant Cell giving:
If Cell.Value = i.Value Then
Cell.Offset(0, 1).Select
Cell.Value = Cell.Value + i.Value
End If
This would make a little more sense but not much. You search Range("G2:H200") of every worksheet for a value that matches a value in Range("A24:A224") of the summary worksheet. If you find that matching value you add it to the next cell in Range("A24:A224"). You tell us nothing about the summary worksheet or the data worksheets so this may be sensible but it does not feel sensible. If you find a match on "A30", you add the value of "A30" to "A31". But then you search for a match on the amended "A31". I cannot imagine any requirement for which this would be sensible.
Even if I thought this was sensible, I don’t think it will work. If I write:
For X = 1 to 10
: :
Next
I cannot change the value of X within the For Loop. I have not tried recently but my recollection is that the attempt to change X is ignored. You are trying to change the equivalent of X for a For Each statement. I have not tried but I suspect your attempt to change Cell will fail. Even if it can change Cell you should not. Select is a slow command and you should only use it if it is essential. Try something like:
If Cell.Value = i.Value Then
Cell.Offset(0, 1).Value = Cell.Offset(0, 1).Value + i.Value
End If
I hope the above helps. If it does not, please provide details of the two ranges so I can better understand what you are trying to do.
I just tried this and it worked perfect.
Sub GenerateTheFormula()
Dim x, Formula
Formula = "=SUM(" 'Formula begins with =SUM(
For x = 3 To Sheets.Count
Formula = Formula & Sheets(x).Name & "!A1," 'Add SheetName and Cell and Comma
Next x
Formula = Left(Formula, Len(Formula) - 1) & ")" 'Remove trailing comma and add parenthesis
Range("B1").Formula = Formula 'Where do you want to put this formula?
End Sub
Idea from here:
Excel VBA Sum from Multiple Sheets
I have multiple sheets in excel that all have a "Name" column. I want a list with all of these combined, without duplicates. A pivot-table cannot do it from my understanding, and when trying this http://www.cpearson.com/EXCEL/TableToColumn.aspx, I only get results from column A:A. The example however, suggest that A:A, B:B, C:C should be combined in D:D when I name D:D "ColumnData" and the table "DataTable" (the naming doesn't seem to be wrong, since I get some result).
Any help? This is the code I use and have put in D2 (just changed commas to semicolons for the local of my Excel):
=OFFSET(DataTable;
MOD(ROW()-ROW([ColumnData]);ROWS(DataTable));
TRUNC((ROW()-ROW([ColumnData]))/ROWS(DataTable));1;1)
Additional info:
First I have pivot-tables to make a list without duplicate names from my sheets (as they consist of a lot of data). Then I have a name for it (name manager) with the formula:
='Name lists'!$A$2:INDEX('Name lists'!$A:$A;MATCH("*";'Name lists'!$A:$A;-1);1)
..and call that "NamesSheet1" for example.
I then populate A:A in my table with:
=IFERROR(INDEX(NamesSheet1;MATCH(NamesSheet1;NamesSheet1;0));"")
..and drag that formula down to more rows than there are names. Then I repeat for each new column, B:B, C:C.
Rename a new tab in your workbook as Master. and run the below code.It will copy all the data in different tabs to Master tab. let me know if this is what was required or any other changes required.
Sub ttest()
Dim wb As ThisWorkbook
Dim ws As Object
For Each ws In ActiveWorkbook.Worksheets
ws.Select
ActiveSheet.UsedRange.Copy
Worksheets("Master").Select
i = Range("A65536").End(xlUp).Row
Range("A" & i+1).Select
ActiveSheet.Paste
Next
End Sub
I fixed it to my satisfaction by going with the "ColumnDataR"-option from the linked example, and then making a pivot-table from THAT column (as the "ColumnDataR"-column did not remove duplicates. Then I made a NEW name list (name manager) based on the new pivot-table. A bit of a long way around it, though now I just need to enter my Raw Data into the sheets, then refresh all data.
I read multiple Q&A's, however it's difficult for me to really understand all the long scripts with the usage of different objects.
I am trying to select a range from one worksheet to an other.
I want to keep the range dynamic, because the range can vary every time. By doing so I have used the following script:
Dim range As Long
For range = ActiveCell To ActiveCell.End(xlDown)
Sheets("Stock Report").range("A4" & range).Value =
Sheets("Unique File").range("Y8" & range).Value
However it doesn't do anything.
This script does work, but I would like to keep the last cell dynamic:
Sheets("Stock Report").Range("A4:A9000").Value =
Sheets("Unique File").Range("Y8:Y90004").Value
I have to do this for multiple columns which are calculated by using other files in a different worksheets and need to sort them finally without all the calculations in an other one.
Any suggestions?
OK try.
Sheets("Unique File").Range("Y8:Y" & Sheets("Unique File").Range("A4").End(xlDown).Row + 4).Copy
Sheets("Stock Report").Range("A4").PasteSpecial Paste:=xlPasteValues
Range("A4").End(xlDown).Row gets the last row of the data on the Stock Report sheet and is used to copy down to the same row on the Unique File sheet. I added 4 because your range starts on 8 on the Unique File sheet.
I think your code didn't work because you were trying to use the "range" you created from the Stock Report sheet on the Unique values sheet.
I would like to be able to reference the next worksheet in a workbook using VBA, but avoid referencing the sheet name as I hope to be able to apply the macro to a number of different workbooks.
I am writing an Excel Macro which is for formatting an excel chart. In the chart's series title I would like to make the series name reference a cell in the next worksheet.
I have tried the following which is not working:
ActiveChart.SeriesCollection(1).Name = "='ActiveChart.Next.Select'!$B$1"
However this is not working.
What is the most effective way of getting the series name field of a chart to reference a cell in the following worksheet within a macro?
I have also tried the following, which does not work either:
ActiveChart.SeriesCollection(1).Name = "=Sheets(1)!$B$1"
Please bear in mind that this is a workbook which is structured with a chart, then a sheet, chart, sheet and so on...
You can use this one-liner
ActiveChart.SeriesCollection(1).Name = "='" & Sheets(ActiveChart.Parent.Parent.Name).Next.Name & "'!B1
Sheets(ActiveChart.Parent.Parent.Name returns the name of the next sheet.
The pair of ' are important to use when referring to sheetnames. i.e. a sheet named My Sheet won't work as My Sheet!B1, it must be 'My Sheet'!B1
Looks like you are trying to put VBA code instead of classical Excel formula reference. I havent ever tried it but I pressume that it wont work. If you want to reference something to a cell you must create the formula in that good old clear syntax with =, sheetname, !, cell address something like:
=Sheet1!A1
You can ofcourse use VBA to create this formula for you and assign it to the field. Try this code:
Dim ws As Worksheet
Dim formula As String
Set ws = ActiveSheet.Next
formula = "=" & ws.name & "!A1"
ActiveChart.SeriesCollection(1).name = formula