Working with Changing Named Ranges Excel VBA - excel

I am writing a fairly lengthy macro in Excel VBA. I want to use named ranges instead of specifying it in the macro. This macro is intended for long-term use. What happens if the range shifts by another user? How can I adjust my code so my named ranges can accommodate for changing positions?

I (personally) hate named ranges. Especially, when you are copying or pasting sheets / ranges from one file to another you always end up with dead-references or copied over named ranges which do not work anymore or got renamed (because they existed already in that file).
My solution to this is one of the following two:
(1) I dedicate a certain part (or even module) in the VBA to declaring my ranges in global variables. This is very similar to the Dim of all variables at the beginning of each sub.
'*********************************************************
'** Declaring all ranges and where to find which data
'*********************************************************
Dim rngNamedRangeName As Range
Sub SetupAllGlobalVariables()
Set rngNamedRangeName = ThisWorkbook.Worksheets(1).Range("A1:C10")
End Sub
'*********************************************************
'** After that all your normal subs follow and whenever
'** necessary you can call the above to get your ranges
'*********************************************************
Sub ExampleCodeToFormatYourRanges()
Call SetupAllGlobalVariables
With rngNamedRangeName
.Interior.ColorIndex = 36
End With
End Sub
(2) Yet, my preferred second solution is to have a separate very hidden sheet where I reference / link all the ranges (which are important to me) again. So, basically, I have in this separate sheet all the "important" data again. This would be your named ranges. But nobody is allowed to touch this sheet (that's why its very hidden). If any of your ranges get shifted or changed then it is easy to re-link the ranges on this hidden sheet with the other sheets again. Yet, on the hidden sheet all data is still in the same spot and allows you to hard-code all ranges in your VBA (taken from the hidden sheet only).
Even non-VBA programmers can normally fix such things with the second method. With the first method you'll probably always need someone with VBA skills to fix it.
Note, the above is not the one and only solution nor might it be the best solution. But I can certainly say that this has proven to be a usable solution even for larger corporations.

Related

Is it not a good Idea to use the Set Worksheets method multiple times during code execution?

I am attempting to copy different images to different worksheets of my Workbook using the following code below. I am changing the Target Worksheet Dynamically in a different sub, with a String Variable in the Global Declarations section. I can see the variable being passed to the sub and in fact it works the first pass through the code, but when I attempt to change the "TargetSheetIni" variable to a new sheet, it continues to use the first original sheet as it loops through.
Can you not change a target sheet after using the Set keyword? Should I refer to the sheet directly instead?
Sub Test1()
Dim TargetWS, SourceWS As Worksheet
Set TargetWS = Worksheets(TargetSheetIni)
Set SourceWS = Worksheets("Images")
DoEvents
SourceWS.Shapes(CurrentImageId).Copy
DoEvents
TargetWS.Paste Range(ColumnLetter2 & RwCnter)
DoEvents
End Sub
I think I may have figured it out. As far as I can tell the issue may be that I used the Copy Sheet Functionality in Excel when I originally created the target sheets. And even though I renamed the sheets both on the tab below and in the project editor... for some reason VBA kept targeting only the original sheet
I proved this by changing my code around to explicitly call the sheet I wanted to target like so:
ActiveWorkbook.Worksheets("Sheet2").Paste Range("I2")
And even doing that it would target sheet 1 for the paste command instead of the expected sheet 2. I deleted the three copy sheets and created a new one from scratch and re-executed code and now it targets sheet 2 as expected.
I found this article that sort of explains it I guess...
https://www.spreadsheetsmadeeasy.com/7-common-vba-mistakes-to-avoid/
Ok my last answer may have not been correct. It appears as though for some reason inserting an ws.activate caused my code to start workin.g
Very frustrating fix. as I have always heard to avoid using that.

How to copy specific parts of a table from a sheet to another

I'm trying to get some details copied in Excel from Sheet 1 columns 1-5 to Sheet 2 columns 1-4, but only for lines that include text or values on sheet one under a specific column (in this case, Column 2). There are other columns in between, so I need to be able to use exact columns rather than A:D for example.
Example of what I'm trying to achieve:
I have tried using a simple IF function with A:A<>"" so it would include any rows that have any data in them, however this does not seem to copy as I need and occasionally based on my attempts i also get circular reference errors. Additionally, I’m not sure how to make sure this gets pasted at the bottom of a table that will expand with each addition.
I realize a probably easier option would be to simply copy Sheet 1 entirely and use a filter on row 1 to deselect Blanks on A:A, but the sheet has so much more info that it would be a waste, and additionally info is constantly added so I need something scale-able. It also occurred to me now that by doing this i would include info from the "header" and "footer", basically a frozen pane - which I do not need.
Could this be done via a simple function, or would it require a Macro?
Please keep in mind I'm rubbish at programming, just trying to make my life easier and learn as I go. A lot of excel forums help but still I'm no coder. I can understand to a pretty big degree what the code does and can adjust accordingly though :)
As suggested, this cannot be done with formulas. There are different ways to achieve this.. below is one approach:
Sub CopyFilteredRows()
Dim oSourceSheet As Worksheet: Set oSourceSheet = ThisWorkbook.Worksheets("Sheet3") ' Set your source sheet here
Dim oRng As Range: Set oRng = oSourceSheet.Range("A2:E" & oSourceSheet.Range("C" & oSourceSheet.Rows.Count).End(xlUp).Row)
' Set filter on column B
oRng.AutoFilter
oRng.AutoFilter 2, "<>"
' Copy to specified sheet
oRng.SpecialCells(xlCellTypeVisible).EntireRow.Copy ThisWorkbook.Worksheets("Sheet4").Range("A2") ' Change your destination sheet here
' Clear objects
Set oRng = Nothing
Set oSourceSheet = Nothing
End Sub
Paste the above UDF in a Module and then run it whenever you want to perform the copy. I suspect you would have to modify it a bit so that you can cater for your particular scenario but it should give you a start

What is the best way to cut and paste a column with a defined name to a new worksheet, and why doesn't my code work?

I am attempting to efficiently copy columns of data from one worksheet to a second worksheet in Excel using VBA, starting with a defined name for the column.
I am unsure why my code doesn't work. I cannot emphasis enough, how little I know about coding. I am attempting to teach myself VBA in order to manipulate vast quantities of data in Excel.
Function SortDataC()
'cuts and pastes columns from the unsorted worksheet to the sorted worksheet
Worksheets("UnsortedData").Range("DeltaModScore").Copy Destination:=Worksheets("SortedData").Columns(1)
End Function
DeltaModScore is the column header. If I look in defined named it is present on the sheet UnsortedData with workbook scope. Thus, I assume I have screwed up the syntax somewhere?
I have used the term Sheets("UnsortedData").Range..... as well as Worksheets.... as you see above. I've been basically searching the web for code examples and trying to get them to work with my data. Inevitably, I end up with errors I have much difficulty fixing. I hope this is something simple someone can point out.
You only require the single top left cell of a destination to complete a Copy & Paste.
SUB SortDataC()
'COPIES and pastes columns from the unsorted worksheet to the sorted worksheet
Worksheets("UnsortedData").Range("DeltaModScore").Copy _
Destination:=Worksheets("SortedData").Cells(1, "A")
End SUB
Functions are intended to return a value. If you simply want to complete an operation, a sub procedure is more appropriate.

Clear sheet including image without affecting named range definitions

This is a simple request. I am trying to clear the contents of a worksheet before copying over a range from another sheet. There are two things I want to make sure of:
1. The sheet I am copying into (Sheet1) has named ranges defined that make absolute references to cells in this sheet. I want to make sure that these definitions are not affected in any way. The contents will, of course, change when I clear the sheet and copy over data from the other sheet.
2. There are some pasted images in Sheet1. These also need to be cleared out.
I tried the following:
Sheets("Sheet1").Cells.Clear
This seems to ensure point #1 above. Seriously, I don't think there is any danger of this being a problem, but just wanted to mention it. However, the images do not go away. Perhaps this is because I use .Cells.Clear? I can't delete the sheet. How should I do this?
This should do it:
Sub KleanUp()
Sheets("Sheet1").Cells.Clear
Dim sh As Shape
For Each sh In Sheets("Sheet1").Shapes
sh.Delete
Next sh
End Sub

Microsoft Excel: Programmatically create a hidden named range

I am told that the Excel object model permits a Range that is not a part of any sheet, yet contains a set of cells and is denoted by a name in the workbook.
Can anyone explain to me how these fit into the Excel object model and how one would go about creating such a thing programatically (either in VBA or .NET source code).
Thanks.
Your question is a little vague, but I'll give it a shot.
Well, as Dave describes, you can give a specific range of cells on a sheet a "Range Name" which you can then refer to programatically, but that doesn't sound like what you are asking.
It sounds like you are asking "is there an abstract RANGE of cells available to be used by VBA code that doesn't literally exist on any worksheet?" The answer to this is no, even named ranges are simply a convenient reference to a real set of cells on a real worksheet.
You can, however, programatically hide a worksheet so that the user doesn't see it, and still work with cells and ranges on that sheet. Just do:
Sheets("Sheet1").Visible = xlSheetHidden
Sheets("Sheet2").Visible = xlSheetVeryHidden
Sheets("Sheet3").Visible = xlSheetVisible
What's "VeryHidden", you ask?
It means that the user can't go to Format, Sheet, Unhide and make the sheet visible.
So if I'm correctly understanding what you want, just programatically hide one of the sheets, then use Dave's technique to create a named reference to a range on this hidden (or VeryHidden) sheet.
That would be a named range. You can reference a selection of cells, and just type a name where it says 'A1' next to the formula bar. That creates a named range that doesn't change.
Alternatively you can create a named range that is based on a formula, and therefore potentially changes as data in the spreadsheet changes. You do this from the 'Define Name' option (which is in the Formulas Ribbon in Office 2010).
Named ranges can be accessed from VBA, and (I'm pretty sure) from .net.
So you'd access the named range from vba like so:
Range["MyNamedRange"]
Yes, there is a NamedRange control in the Microsoft.Office.Tools.Excel namespace in VSTO. This is a host control which is different from the native Range control in the Microsoft.Office.Interop.Excel.Range namespace.

Resources