excel update reference for named cells and ranges using vba - excel

I would like to create a script in excel vba to change the Reference of a bunch of defined names. I have a revised workbook with updated data and a new name; I would want to change each defined name reference to the updated workbook. For example:
change the reference of the named range
from '[c:\files\[factorsrev1.xls]'!:$K$15:$N$76
to '[c:\files\[newfactorsrev2.xlsm]!:$K$15:$N$76
I tried using the (change-multiple-named-cells-and-ranges) post, as a guide, but so far it hasn't worked.
What I have so far:
Sub RangeRename()
Dim N As Name
For Each N In ActiveWorkbook.Names
N.RefersTo = WorksheetFunction.Substitute(N.RefersTo, "factorsrev1.xls", "newfactorsrev2.xlsm")
Next N
End Sub
Sure would be nice not having to edit each one manually...help is most appreciated.

Related

Access Excel named ranges through a loop using VB.Net

I'm trying to use visual basic for applications to loop through a list of named ranges from an excel sheet as the first step in a process for altering their formulas. Its all part of an Excel plug in I work with using Visual Studo I have a basic loop, which came directly from the MS docs.
Dim n As Excel.Name
Dim names As Excel.Names = destStreetEstimates.Names
Dim test_string As String = destStreetEstimates.Name
MsgBox(test_string)
For Each n In names
MsgBox(Prompt:=n.Name)
Next n
This doesn't work, it looks like com objects are being put together into a list when I turn on the VS debugger (yay), but the com objects aren't being turned into anything useful I can loop through. (boo).
Am I missing something? I've gone through the Docs several times, nothing I've read there matches with the errors I'm getting. But I'm still pretty green.
https://learn.microsoft.com/en-us/office/vba/excel/concepts/cells-and-ranges/refer-to-named-ranges
I've looked at other guides, most of them seemed to be discussing how to programmatically generate named ranges. I have to start with the ranges I've been given, its about 70, and while I have all their names in a config file there's a good chance the sheet will have additional names I haven't been given in the future and my function has to work in that case too.
See https://www.thespreadsheetguru.com/blog/the-vba-guide-to-named-ranges
Sub NamedRange_Loop()
'PURPOSE: Named Ranges in the Active Workbook
'SOURCE: www.TheSpreadsheetGuru.com
Dim nm As Name
'Loop through each named range in workbook
For Each nm In ActiveWorkbook.Names
Debug.Print nm.Name, nm.RefersTo
Next nm
'Loop through each named range scoped to a specific worksheet
For Each nm In Worksheets("Sheet1").Names
Debug.Print nm.Name, nm.RefersTo
Next nm
End Sub

Can't acess ComboBox in VBA

I've created a combobox in an Excel sheet and named it "GraphChoice". It's located in a sheet named "Choose Graph"
In VBA I'm trying to fill it with data using this code:
Sub Choose_graph_and_date()
Dim Graph As Worksheet
Dim FormInfo As Worksheet
Set Graph = Worksheets("Choose Graph")
Set FormInfo = Worksheets("Forminfo")
Graph.Activate
Graph.GraphChoice.List = FormInfo.Range("A1:A3").Value
End Sub
I get an error saying Can't find method. I've also tried.
GraphChoice.List = FormInfo.Range("A1:A3").Value
Then I get error 424. Object Required.
The code is in the ThisWorkbook module since I want it to load every time you open the workbook.
Anyone knows whats wrong?
For a form control, you can use the DropDowns collection...
Graph.DropDowns("GraphChoice").List = FormInfo.Range("A1:A3").Value
Or, you can use the Shapes collection...
Graph.Shapes("GraphChoice").ControlFormat.List = FormInfo.Range("A1:A3").Value
For an ActiveX control, you can refer to it using the OleObjects collection...
Graph.OLEObjects("GraphChoice").Object.List = FormInfo.Range("A1:A3").Value
Or, you can use the Shapes collection...
Graph.Shapes("GraphChoice").OLEFormat.Object.Object.List = FormInfo.Range("A1:A3").Value
Actually, you can also refer to it using the code name for your sheet. So, for example, let's say that the code name for your sheet is Sheet2, you could do the following...
Sheet2.GraphChoice.List = FormInfo.Range("A1:A3").Value
My understanding is that this issue exists, because ActiveX Controls have a different kind of relation (hence referencing) than other common objects (such as cells) towards the sheets. You can solve your problem by either using:
Sheets("Choose Graph").GraphChoice.List = FormInfo.Range("A1:A3").Value
or by changing the object properties of the sheet with your graph to e.g. myGraphSheet and then using:
myGraphSheet.GraphChoice.List = FormInfo.Range("A1:A3").Value
Also if you want the ComboBox to be filled everytime you open it, you need to place your code in ThisWorkbook-Module (as you did) and in a sub with the following name Workbook_Open() :
Sub Workbook_Open()
'code executed when opened
End Sub

Naming a Cell in Excel

I'm trying to create a series of macros to audit some financial models.
The first macro I’m trying to create is one that names the current cell. Why? I want to name the cell, after that I’m going to record a macro to click the “Trace Precedents” and go to the cell that has the relationship.
After that I need to go back to the original cell, thats the named one. That's easy on the go function, but I need to the naming macro working
My recorded code for the naming macro is as follows:
Sub Namer ()
ActiveWorkbook.Names.Add Name:="Name1", RefersToR1C1:="=Workings!R42C6"
ActiveWorkbook.Names("Name1").Comment = ""
End Sub
I have the following problems:
I need to name the current cell on a workbook with a lot of sheets. I’m gonna be moving between sheets but my recorded code has a “fixed” sheet.
How can I fix that? Name the current cell on the current sheet
Something like this should help you ...
Public Sub CreatesNames()
Dim objSheet As Worksheet
For Each objSheet In ThisWorkbook.Worksheets
objSheet.Names.Add Name:="Name1", RefersTo:=objSheet.Range("A1")
Next
End Sub
... something to note, names can be created at the worksheet level or at the workbook level, so, if you're going to be creating the same name across worksheets then you need to use a Worksheet object, not the Workbook object.
So to use the active cell ...
Sheet Level
ActiveSheet.Names.Add Name:="Name1", RefersTo:=ActiveCell
Workbook Level
ActiveWorkbook.Names.Add Name:="Name1", RefersTo:=ActiveCell
I hope that helps.

How to store and use a VBA Function within a worksheet (not workbook)

I keep hunting for an answer on this but seem to be out of luck.
I have a custom Function that I wish to store within a single worksheet such that the function can be distributed with the worksheet (ie not the workbook)
The custom function needs to be called from an excel cell formula
Calling the function when stored in a code module works fine however moving it into the worksheet object 'module' causes it to fail. This is perhaps to be expected.
The reason for wanting the Function placed in the sheet code is so that it is automatically imported with the sheet to a new workbook via the templates folder and can then be used by the rest of the workbook. (this being importing via the Insert>New Sheet Dialog
So my question is 2 fold, either:
How can call a function from an excel formula when the function is written in the worksheet code, or...
How can I automate a module being added to a new workbook when I add a sheet from a template file?
Of note, using the personal.xlsb file will not work for this and I need to be able to call the function from within a sheet formula
Thanks in advance
You can add the following to the ThisWorkbook events, of the workbook the sheet is being imported to, tweak as you like. I have a worksheet function in Sheet1, called ns it takes two arguments a and b, the function in excel I wish to use is MY_FUNCTION
This adds a module to hold the wrapper to the worksheet function.
Private Sub Workbook_NewSheet(ByVal Sh As Object)
Dim vbp As VBProject
Dim vbm As VBComponent
Set vbp = Application.VBE.ActiveVBProject
Set vbm = vbp.VBComponents.Add(vbext_ct_StdModule)
vbm.Name = "MY_FUNCTION_MDL"
' vbm.CodeModule.AddFromFile "" ' <--- another way add from file
vbm.CodeModule.InsertLines 1, "Public Function MY_FUNCTION(a,b)"
vbm.CodeModule.InsertLines 2, " MY_FUNCTION=sheet1.ns(a,b)"
vbm.CodeModule.InsertLines 3, "End Function"
End Sub
You can do this (it works for me):
Option Explicit
Private Sub Workbook_Open()
ThisWorkbook.VBProject.VBComponents.Import "[PathtoDir]\MyMod.bas"
End Sub
Make sure to do the following in excel:

Excel VBA: Formatting Based on The Format of Another Cell, Getting Method Error

I'm working on a spreadsheet that breaks out the tasks in a given department. Each task is then assigned to a person in that department using a data validation drop down that dynamically fetches values from the tables that list each employee/role in the department. The tables are on a different sheet than the task breakdown.
Each individual needs their own background color that automatically fills in when their name is selected from the drop down on the tasks sheet. What I'm hoping to do is write a macro that looks for that person's name in the table (note that I'm using named ranges) and then matches the formatting of the selected cell to their row in the table. I'm a super beginner with VBA and have hit the end of my abilities. Several answers that come close to what I want to do, but in terms of adapting it for my specific use case, I'm stuck.
I grabbed code from this thread, which is essentially the result I want to achieve, except that their key is on the same sheet and mine can't be: https://superuser.com/questions/472918/excel-conditionally-format-a-cell-using-the-format-of-another-content-matching
So far, I've compiled this:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If VarType(Target) > vbArray Then Exit Sub
' if multiple cells are changed at once, then exit
Dim kr1 As Range
Dim kr2 As Range
Dim KeyRange As Range
Dim TargetRange As Range
Dim lCell As Object
Dim kCell As Object
Set kr1 = Application.Range("ESFormattingRange")
Set kr2 = Application.Range("CSFormattingRange")
Set KeyRange = Application.Union(Range("kr1"), Range("kr2"))
' formatting key is here
Set TargetRange = ThisWorkbook.Worksheet("Sheet3").Range("A:X")
' changing cells in this area
For Each kCell In KeyRange.Cells
If kCell.Value <> "" Then
For Each lCell In TargetRange.Cells
If lCell.Value = kCell.Value Then
' only change cells that match the edited cell
lCell.Font.Color = kCell.Font.Color
lCell.Interior.Color = kCell.Interior.Color
' copy whatever you feel needs to be copied
End If
Next
End If
Next
End Sub
When I run this, I get the following method error, but no lines are highlighted when I try to debug:
Compile error:
Method or data member not found
I'm thinking maybe there's something wrong with the way I've constructed my range variables, but I've googled everything I can think of and I'm at a loss.
Any help is greatly appreciated!
The VBE should be highlighting the word Worksheet in ThisWorkbook.Worksheet("Sheet3").Range("A:X").
"Method or data member not found" means Worksheet isn't a member of ThisWorkbook.
You can fix this by pressing CTRL+SPACE to autocomplete the member name to Worksheets.
Alternatively, you can re-type the . dereferencing operator after ThisWorkbook, and press TAB when the names list dropdown is shown, highlighting the Worksheets member - that will also autocomplete the member name to Worksheets.
Rule of thumb, if you type a . dereferencing operator and then type something that isn't in the names list, you can expect this compile error.
When you make this typo against a Variant or Object variable, the code will happily compile, but error 438 will be thrown at run-time - like this:
ThisWorkbook.Worksheets("Sheet3").Ragne("A:X") ' <~ typo compiles. Option Explicit can't save you.
The reason is that Worksheets returns an Object reference, so any member calls chained to it are resolved at run-time. A safer way to code is to declare a local Worksheet variable to hold this object, and then work with that object instead:
Dim sourceSheet As Worksheet
Set sourceSheet = ThisWorkbook.Worksheets("Sheet3")
sourceSheet.Rnage("A:X") ' <~ typo throws at compile-time now!
If the worksheet object exists in ThisWorkbook at compile-time however, then it's probably a better idea to work with its code name instead. Locate Sheet3 in the Project Explorer (CTRL+R), then find its (Name) property - change it to e.g. SourceSheet. And then you can do this:
SourceSheet.Range("A:X") ' <~ a typo wouldn't compile here.
...without needing to explicitly declare a SourceSheet.

Resources