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.
Related
I'm working on a routine that will populate a worksheet from data on a second worksheet in the same active workbook. The location on the destination worksheet is relative to a given cell which is the active cell on the relevant worksheet. In order to avoid continually swapping between active sheets, I was hoping that I could reference the destination cell using the 'offset' method, however I can't get it to work. My code line would be something like this:
Worksheets("DestinationSheet").activecell.offset(Rowoffset:=x, ColumnOffset:=y).Value=DataValue
Where x, y, and Datavalue are variables.
How about
Worksheets("DestinationSheet").range(activecell.address).offset(Rowoffset:=x, ColumnOffset:=y).Value=DataValue
?
The activecell is only a single cell on the active sheet so cannot be located on another sheet (and that sheet must be active when the macro is run). Btw it's not a good idea to base code on the activecell if you can avoid it.
That said, I'm not sure I understand what you are doing.
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.
I have an excel workbook with multiple sheets that aggregate costs and revenues of different technological components (set up in different sheets) in a system.
I want to have a main worksheet, where users can change a small selection of important variables from the technology sheets. I also want those important variables to be defined and editable on the technology sheets.
I've been using named ranges to manage variables, but I'm not sure how to link two cells on different sheets to one variable. For example, I want to name a variable "oilprice" that is referenced in different formulas. I want to be able to change the variable "oilprice" from the main worksheet and the electricity technology sheet in my workbook.
Similarly, I want to be able to check a box on both sheets for "Turn on Electricity" and have the checkbox on the other sheet change as well.
I've been looking around on google and stackoverflow but can't find an answer. Thanks!
Named range, option 1: "override" style formula
With named ranges, you are not able to update the value from multiple cells. You could use logic in a formula to look at a "override" cell and pass that value to the actual named range. This works if the number of overrides is small. That style of formula looks like:
=IF(ISBLANK(oilprice2), oilprice1, oilprice2)
Where oilprice1 and oilprice2 are the cells that hold possible values. Note that there is an implied order in these which can get confusing after a while. That is, if oilprice2 has a value, it will not change oilprice1 nor will oilprice1 be considered.
Named range, option 2: scroll bar or spin control
Another option similar to the checkboxes below, is to use a spin control or scrollbar control to update the values. Those work across multiple sheets.
Checkboxes across sheets
For the checkboxes, this is handled by the Cell Link. You can set as many checkboxes as you want to control a single cell's value.
Here is an example with two checkboxes sharing the same Cell Link = $C$2. They both change when one is clicked.
Okay, I figured out how to have two cells to refer to the same value.
I named a range "oilprice" on the "electricity" sheet.
The cell to input oilprice on the "main" sheet has the formula "=oilprice" and is named "oilprice2", showing the value on the "electricity" sheet "oilprice" named range.
Then I made the following vba code which updates the "oilprice" cell on the electricity sheet when you change the "oilprice2" cell on the main sheet and reverts back to the formula showing "oilprice":
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("oilprice2")) Is Nothing Then
Application.EnableEvents = False
Worksheets("electricity").Range("oilprice").Value = _
Worksheets("main").Range("oilprice2").Value
Worksheets("main").Range("oilprice2").Value = "=oilprice"
Application.EnableEvents = True
End If
End Sub
I am trying to look up some data in an excel sheet to populate a field in a Lotus Notes app on demand. I am using an Action button with LotusScript like so:
Dim v As String
Dim v2 As String
'Open XL sheet for access to data
Set oExcel = CreateObject ( "Excel.Application" )
v="\\msp2\mi\CSD\Confidential\IT and PPST budget.xlsm"
Msgbox("opening " & v)
Set oWorkbook = oExcel.workbooks.open(v)
Set oWorkSheet= oWorkbook.worksheets (4)
v2=Cstr(oWorkSheet.Cells(1,1).value)
Messagebox(v2)
This code does work in that it pulls data from cell A1 - but which sheet?
The sheet containing the data I want is "Sheet4" renamed as "Logic-Detail" but if I use 4 as a parameter as above I get data from the 4th sheet from the left. I need to be able to cope with sheets being hidden as well. I spent 20 minutes on MSDN's excel object model "help" getting nowhere :-(
I feel sure it must be dead easy when you know the answer !
Guessing at the correct syntax is frustrating, isn't it? When referring to sheets in Excel-VBA there are several options:
You can list them by index-number, as you already did in the code-sample in your question
You can refer to it by its name, in your case this would probably be oWorkbook.Worksheets("Logic-Detail")
You can refer to it by its codename, in your case this would probably be oWorkbook.Sheet4. The codename can be changed when you view the properties of the worksheet in the VBA editor.
There may be even more ways to refer to the sheet, but these are the ones which come to mind at the moment. As we know from the question and comments, at least the two first options also work in LotusScript.
I am new to excel vba and I have some questions regarding referencing a worksheet
I noticed that when I used
Worksheets(3)
The worksheet would be obtained according to the sequence of the worksheet in the workbook
When I used
Worksheets("Name")
It would be retrieved according to the name of the worksheet
However, I found that both approach is troublesome because for method 1, I need to fix the sequence of the worksheet. Once I dragged the worksheet around, the reference would become incorrect.
Method 2 would need me to fix the work sheet name , which is not that flexible.
I noticed that at the left panel of VBA editor, under the Microsoft Excel Objects, whenever the worksheet is created, a new sheet like
Sheet1 (Name) would be created.
Is there any way that I could reference the worksheet based the the Sheet1 variable, which I could fixed it so that I could freely drag the sheet around or change the worksheet name?
Thanks.
The name you refer to is called the CodeName. You can refer to a sheet by this name.
Eg, for your example Sheet1 (Name) can be referenced as
Worksheets("name")
or
Sheet1
Eg Worksheets("name").Activate or Sheet1.Active would both work
Note that you can change this name to something meaningful in the Properties window of the VBA IDE, but you can't change it at run time