I have a VBA enabled excel workbook which has more than 20 sheets. Now the code in the VBA is using Worksheets numbers to call the worksheets.
Now I will have to delete one sheet which makes all the code unusable because if I delete one sheet the worksheet number changes.
Example Worksheets(10).Activate will point to another worksheet since I will be deleting the third worksheet
I am fairly new to this, so what would be the fastest way instead of manually changing the worksheet number in the code.
Note that there are 3 ways to access a sheet …
by its position in the tab bar:
Worksheets(10) gives the 10ᵗʰ worksheet in the tab bar.
Note that if you also have eg chart sheets the numbering is different from Sheets(10) which then might be a completely different sheet.
by its visible tab bar name:
Worksheets("Sheet10")
by its VBA name:
Sheet10
Note that the VBA name can only be changed in the Project window of the VBA-Editor.
Note that Worksheets(10), Worksheets("Sheet10") and Sheet10 can be completely different sheets, because they use 3 completey independ naming systems.
Which one to use highly depends on what you are actually trying to do. There is no best option in general each of them has their advantages and disadvantages.
Additionally I highly recommend not to use .Activate and .Select at all. Therefore read How to avoid using Select in Excel VBA.
Related
I know how to lock and protect selected cells in a sheet. But are there any way to do it in one sheet, and then it counts for all the sheets. I want to lock the selected yellow cells, in all the sheets.
This can be done in one go using the UI:
Select all the sheets (shift-click on the tabs)
Select the range on one sheet (which selects it on all the selected sheets)
lock the cells (this does the same for all selected cells)
Unfortunately the VBA Range object does not support "3D ranges" spanning multiple sheets so your options within code are:
loop over the sheets and set the Locked property of the appropriate range for each sheet
code the equivalent to the UI version above (using Select. This works as Selection can include ranges from multiple sheets)
I would always go for the first option in code - using Selection is slow and very prone to bugs see this question for more. And I can't think of any reason you would need to do it "in one go" when a loop is readable, fast and reliable.
-- Edit: this is now part of the bigger question of how to reliably move sheets about --
I've got a workbook which has sheets containing tables and sheet-scoped named ranges. Some of these sheets' formulas link to some of the names on other sheets (i.e. =Sheet1!Sheet1LocalName somewhere on Sheet2).
The time has come for me to create VBA code that moves these sheets into another workbook. Doing so, I of want all existing functionality to remain intact.
When looping over all sheets individually and Worksheet.Move -ing them one at a time to the other workbook, the range name links between the formulas get broken. E.g. when Sheet2 uses a name on Sheet1 in one of it's formulas:
Move over Sheet2;
Sheet2 will still correctly link to Sheet1 back in the source workbook.
Move over Sheet1 itself;
Excel 'helpfully' creates a workbook-scoped name of the same name for me as the name Sheet2 linked to (even if it didn't exist before), where
this new name does point back to the already moved sheet in the destination workbook, after which
the already moved Sheet2's links get modified to point to this new workbook-scope name in the source workbook, thus
messing up the link beyond repair.
Even if I could overcome this by analyzing the formulas beforehand to scan all sheet dependencies, since sheets may have links going both ways between them, it seems I can't do it this way.
When moving all sheets in one go using ThisWorkbook.Worksheets(Array(name1, name2)).Move, I get the Excel error "You cannot copy or move a group of sheets that contain a table".
So it seems I'm sorely out of luck here... There's of course the options of:
moving the sheets individually and rebuilding all formulas afterwards, and
replacing all tables with ranges and rebuilding all tables afterwards
but I'd understandably do not want to go there, since I do not control what goes on the sheets...
Any alternatives?
-- Edit --
The true purpose of this question is that I need to move the sheets over to a temp .xlsx workbook, save/close/re-open that workbook, and then move them back again to the original .xlsm workbook, thus scrubbing them off of their VBA module. See my other SO post for the background, though when I wrote that question I envisioned only needing to scrub the 1 topmost sheet in the ranged-name linking hierarchy, but it turns out I need to do it for all sheets to be safe enough.
After a lot of trial-and-error I found out that moving or copying all sheets in one go just isn't doable because of the tables on them, and handling them one at a time really messes up formulas and named ranges linking them together (even .Copy has similar unwanted side effects to using .Move). While I could in turn write code to 'fix' these broken names or delete these 'helpfully added' rogue names, I wouldn't be surprised if other range linking mechanisms (like chart source, pivot source, data validation list source, form control linked cells, etc.) also acted up badly, making this an even bigger mess to deal with...
I've created a chart in a workbook. I want to copy and paste that chart into another workbook in such a way so that when I update the original data it automatically updates both charts.
Between Excel and Word there are no problems: I can paste the chart as link (see below):
but in Excel the same option seems to be disabled:
Any idea to solve my problem? The chart copied in the destination only updates if the original file is open, and the data changed!
Many thanks in advance.
I've not done this much, but when I have I generally just paste (i.e. Ctrl+C). The chart series should be automatically updated to refer to the source workbook, the relevant worksheet within that workbook, and keep the cell ranges the same.
So my thought would be that the option isn't disabled, it's just implicitly built in to the normal paste. Which would make sense; The use-case for keeping the same source range of cells, but on the new worksheet being pasted to (even inside the same workbook, let alone in a different workbook) is not exactly one that seems crazy useful.
Currently: I have a few sheets that contain one or more tables (e.g., Sheet1 has one table while Sheet2 has three tables). These same sheets are found in several end user workbooks. The tables in those sheets are used by structured references within cell formulas in the workbook.
Goal: I would like to have another workbook (a master workbook) that only has the sheets that contain the tables. Updates would be manually made to the master workbook i.e., add a row, delete a row, edit a row, add a column, delete a column, edit a column. Once updates are completed with the master workbook, the updated [master] sheets would then be placed into the various user workbooks, replacing the existing sheets and thus the tables (using VBA)...without breaking the structured references! No #REF errors! Well, this is what I'm envisioning, however, it doesn't have to be exactly this. Also, the common table sheets must be in the end user workbook, no external referencing! Unless it's part of the process to make what I need work, of course :-)
I'm very handy with VBA but not a MVP. Assume all of the workbooks -- both end user and master -- exist in the same directory. The master workbook would contain the code that would deliver the updated sheets to the end user workbooks. Excel 2007 & 2010 in Windows 7 environment.
I don't have any code as I'm trying to manually figure it out first without breaking anything. Suggestions welcomed! Thank you.
[Update 13Jun2012] Hopefully this more long-winded explaination will help.
What I'm doing:
I have a workbook that (essentially) copies itself into an end user workbook (1 to n times based on user form inputs). The end user workbook is protected to keep end users from making mistakes in certain formulas (various forms of sheet/cell protection). There are some sheets that contain tables and these tables are the same for all users. These tables are used for data validation (e.g., Allow: List; Source: =timing_droplist) and VLOOKUPs (e.g., =VLOOKUP($W8,Timing_table,FE$5+1,FALSE)). These end user workbooks are created once a year but updated three times during the year (they're for finance/budgeting). The tables can be updated at any time. Since data is added to the end user workbooks it's not convienent to re-generate those workbooks with the updated tables and then have the end user re-enter all their data. So it would better if the existing end user workbooks could have the common tables updated all together (using VBA).
What's happening (just ONE example):
"Timing" sheet exists and contains the table "Timing_table". If the master "Timing" sheet is added to the workbook, Excel renames it to "Timing (2)". This is normal. But the table in the added sheet becomes local instead of globle AND it, too, gets renamed, FOR EXAMPLE, "Timing_table12". I don't know how Excel comes up with the digits for the table name and they could change. If I delete the old "Timing" sheet all references to it are broken (of course) -- pulling up Name Manager shows #REF! in the value column. Renaming the new references doesn't fix the issue because the new references are local to the new sheet.
I tried manually cutting and pasting a table into another, pasting as Text, and that doesn't keep formulas (basically it performs a Paste as Values operation) and, overall, doesn't work. Just looking for options. External references to these tables is not an option.
I think that this thread might help you out: http://www.ozgrid.com/forum/showthread.php?t=66791
To provide you the reply directly (assuming that the problem mainly involves the external referencing):
Replied by Aaron Blood:
Re: Copy Formula To New Worksheet Without Path
You've already developed the code to do the copy/pasting to a new sheet and workbook. Now all you need to do is scan the formulas of the new worksheet and remove the ext refs from the formulas.
Run something like this at the end of your existing copy/paste macro...
VB:
Sub ExtRef_Remover()
Dim cell As Range, n As Variant
For Each cell In Workbooks("New_WB").Sheets("Sheet1").Cells.SpecialCells(xlFormulas)
n = Application.Find("]", cell.Formula)
If Not IsError(n) Then
cell.Formula = "='" & Right(cell.Formula, Len(cell.Formula) - n)
End If
Next cell
End Sub
Using extensive external references just didn't work out in this project so I convinced the project manager that we needed to change course. She agreed that what she wanted was too much to ask and taking too much time to implement, aside from compromising workbook generation and stability. I ended up using a data pull into the necessary tables via a command button. Waaaay easier to work with and stable.
Suppose I have several rows of data across different spreadsheets in the same workbook and I want to display (in a separate spreadsheet) only the rows which contain a specific string. How would I do that?
Without macros this gets a little clumsy, but one way to do it is with linking and filtering.
In your separate workbook, copy all the rows from the several worksheets that might be of interest and make sure that they are linked to the source workbook or worksheets. (If you are doing all of this from within the same workbook, you don't have to worry about the external linking.)
Then apply filtering to all of these rows, and set up your filter to look for the specific string that you need.
To reiterate #Stewbob's comment, there isn't really a 'clean' way to do this using only Excel formulas and little manual work.
As I don't believe OP required the work to be done in a separate workbook, you could just copy/paste all data into an additional worksheet and filter on the desired string should get you the results you're looking for.