IN VBA
Function SNAME(number As String) As String
Dim WORD$
WORD = "Sheet" + number
' SNAME = Worksheets(1).CodeName
For i = 1 To ThisWorkbook.Worksheets.Count
If Worksheets(i).CodeName = WORD Then SNAME = Worksheets(i).Name
Next i
End Function
IN EXCEL
=SUMIFS((SNAME(19)!$T$2:$T$9962),(SNAME(19)!$A$2:$A$9962),"=31",(SNAME(19)!$C$2:$C$9962),"<="&EDATE(TODAY(),-12))
Purpose:
The idea here is that I want to pass the sheets name to the range function based on its code name. the VBA function SNAME seems functional and returns the worksheet's name based on the VBA object code name. When I try to combine that with the range function in the equation, there seems to be an error I'm unsure how to resolve. When I replace SNAME(19) with the sheet name the Equation executes properly.
Goal:
I need to be able to reference the sheet using its code name to avoid future errors of individuals changing the name of the sheets. I'd really appreciate any advice someone might have on the issue.
As far as I know, Excel automatically corrects the formula if any name used there has been changed. So I'm not sure whether you need this construction. Anyway, to make it work we have to change SNAME(19)!$T$2:$T$9962 to something like INDIRECT("'" & SNAME(19) & "'!$T$2:$T$9962").
To make this cleaner, let's put quoting inside the function SNAME. Also, I'd change the type of number to Variant and put Exit For on success:
Function SNAME(number) As String
Dim sh As Worksheet
Dim WORD$
WORD = "Sheet" & number
For Each sh In ThisWorkbook.Worksheets
If sh.CodeName = WORD Then
SNAME = "'" & sh.Name & "'"
Exit For
End If
Next sh
End Function
In the formula, I would use LET to ease editing the function call and to call it once:
=LET(sh, SNAME(19),
SUMIFS(
INDIRECT(sh & "!$T$2:$T$9962"),
INDIRECT(sh & "!$A$2:$A$9962"),
"=31",
INDIRECT(sh & "!$C$2:$C$9962"),
"<=" & EDATE(TODAY(),-12)
)
)
Related
I need your help. I found the attached vba code but when I run the code I am getting a very strange 1004 error. Could you please give an explanation or try to fix this error?
Thank you so much all!
' Module to remove all hidden names on active workbook
Sub Remove_Hidden_Names()
' Dimension variables.
Dim xName As Variant
Dim Result As Variant
Dim Vis As Variant
' Loop once for each name in the workbook.
For Each xName In ActiveWorkbook.Names
'If a name is not visible (it is hidden)...
If xName.Visible = True Then
Vis = "Visible"
Else
Vis = "Hidden"
End If
' ...ask whether or not to delete the name.
Result = MsgBox(prompt:="Delete " & Vis & " Name " & _
Chr(10) & xName.Name & "?" & Chr(10) & _
"Which refers to: " & Chr(10) & xName.RefersTo, _
Buttons:=vbYesNo)
' If the result is true, then delete the name.
If Result = vbYes Then xName.Delete
' Loop to the next name.
Next xName
End Sub
These Excel built-in range names appear in the Excel name manager when using SUMIFS,IFERROR, COUNTIFS and other formulas.
There are a lot of ways around this, as suggested in the comments.
You can add either of these:
If Not xName.Name Like "_xlfn*" Then
'Or
If InStr(xName.Name, "_xlfn") = 0 Then
first thing in the loop (don't forget to close it), or something similar.
If you for some reason still want to see it, you can add it to the delete if:
If Result = vbYes And Not xName.Name Like "_xlfn*" Then xName.Delete
After a recent windows update, a previous Excel vba script that was working, no longer functions correctly.
The macro operation, when working, opens a csv file that is defined in the active workbook as String aString. The csv file contains a list of variables and corresponding values for those variables. The macro returns the original active workbook and reads the defined named cells in the active workbook and updates those named cells with the values defined in the csv file.
The issue appears to be that despite returning to the original active workbook the command to generate the For loop to cycle through the named cells no longer returns a value for the variable name or which worksheet the variable lives in.
The command is:
' Process to update name values
Workbooks(strWorkBook).Activate
' Windows(strWorkBook).Activate
' Dim nm As Variant
' For Each nm In ActiveWorkbook.Names
For Each nm In Workbooks(strWorkBook).Names
varname = nm.Name
MsgBox "varname " & varname & " nm " & nm
varsheet = Range(nm).Parent.Name
MsgBox "varsheet " & varsheet
The message for the varname is now:
The message should read varname aString nm $D$4
Pretty sure it is update version related, as in Excel build Version 1902 (Build 11328.20318) it works but not in Version 2002 (Build 12527.21416)
Thanks in advance for your help. Related forums point to security update issues with Windows but no solutions I can implement yet.
======================================================
Update from further testing:
I created a new workbook and built the macro that is failing in the new workbook using Excel Version 2002 (Build 12527.21416). The macro runs perfectly in the new version of the Excel file but continues to produce the error message above in the legacy file.
I'm suspecting there are some issues related to security updates in the Version 2002 build that are not compatible with the Version 1902 build but cannot identify what the issues are.
The macro that runs in the new version but not the original document is:
Public Sub testName()
Dim filePath As String
Dim inFilePath As String
Dim inCase As String
'On Error GoTo ErrorHandler
Application.ScreenUpdating = False
Application.EnableEvents = False
'----------------------------------
' Find path for input file
strWorkBook = ActiveWorkbook.Name
' MsgBox strWorkBook
filePath = Range("aString").Value
tmpsep = InStrRev(filePath, "\")
' Input file workbook name
inCase = Right(filePath, Len(filePath) - tmpsep)
'Input file full path
inFilePath = Left(filePath, Len(filePath) - Len(inCase))
' Open input data file
Workbooks.Open Filename:=filePath
'' Find last row in file
' Call FindLastRow.FindLastRow(lRow)
' rngend = lRow + 2
'' MsgBox rngend
Workbooks(strWorkBook).Activate
'
' VBA script to read external CSV file' For Each nm In ActiveWorkbook.Names
For Each nm In Workbooks(strWorkBook).Names
varname = nm.Name
MsgBox "varname " & varname & " nm " & nm
varsheet = Range(nm).Parent.Name
MsgBox "varsheet " & varsheet
varcell = nm.RefersToRange.Address(False, False)
NextIteration:
Next nm
End Sub
Your problem stems from the misdeclaration of the variable Nm. In fact, it's not declared (and you are missing Option Explicit at the top of your module) which makes it a Variant. Excel appears unable to fit the Name object into the variant as you intend within the rather complicated environment you create (more about that further down). This code will work.
Dim Nm As Name
Dim varName As String
Dim varSheet As String
Dim varCell As String
' For Each Nm In ActiveWorkbook.Names
For Each Nm In Workbooks(strWorkBook).Names
With Nm
varName = .Name
varSheet = .RefersToRange.Parent.Name
varCell = .RefersToRange.Address(0, 0)
End With
MsgBox "Named range """ & varName & """ refers to range" & vbCr & _
varCell & " on sheet """ & varSheet & """."
Next Nm
I tested the above code on the ActiveWorkbook but it should work on any other as well. I tested in Excel 365 but that shouldn't make a difference, either.
The complication mentioned above stems from this part of your code, Range(nm).Parent.Name. In this context nm is a string. But in the context of your loop nm is a Name object. So, whereas in the older version apparently the default property of the Name object was the referenced range address it now would appear to be something else. It doesn't really matter because the Name object has several properties from which the referenced range can be extracted as a range or its address, and once you specify the one you want to use there is no need to ask VBA to use the default.
Incidentally, Range("anything")will always be on the ActiveSheet, and Range("Sheet13!A2:A4").Parent will return an error rather than Sheet13. Therefore, if you need to know the sheet of the range on which the named range resides you should look for another method of getting at it.
Problem solved thanks to this thread stackflow thread and user Jenn.
It seems that between Excel V1902 and V2002 a hidden variable _xlfn.SINGLE exists in the workbook. When the macro loops through, it sees the named range, cannot resolve its address or sheet location and stops. Not until running Jenn's code could I see the hidden variable.
The easiest solution was to include an IF loop to bypass this variable if defined and continue as normal (as per below). The sheet is working now but I will not get those 2 days of my life back.
For Each Nm In Workbooks(strWorkBook).Names
If Nm.Name Like "_xlfn*" Then
GoTo NextIteration
End If
With Nm
varName = .Name
varSheet = .RefersToRange.Parent.Name
varCell = .RefersToRange.Address(0, 0)
End With
MsgBox "Named range """ & varName & """ refers to range" & vbCr & _
varCell & " on sheet """ & varSheet & """."
NextIteration:
Next Nm
Thanks to those who commented on the thread and Variatus I will update those declarations.
I have the following vlookup in my code, but the tab 'ASN since 12.1.20 w FO' won't always be named that. However, it will always be the first tab in the workbook. How would I refer to tab/worksheet 1 instead of the name of the tab?
"=VLOOKUP(RC[-6],'ASN since 12.1.20 w FO'!C[-7]:C[9],17,FALSE)&"",""&TEXT(VLOOKUP(RC[-6],'ASN since 12.1.20 w FO'!C[-7]:C[9],14,),""MM/DD/YYYY"")"
'Build' a Formula in VBA
When 'building' fairly complicated formulas, it is a good idea to create a procedure to do just that. Every now and then you run it, until you're satisfied with the result.
If you prefer, you can use a message box instead of Debug.Print.
Option Explicit
Sub FormulaBuilder()
Dim wsName As String: wsName = ThisWorkbook.Worksheets(1).Name
Dim strFormula As String
strFormula = "=VLOOKUP(RC[-6],'" & wsName _
& "'!C[-7]:C[9],17,FALSE)&"",""&TEXT(VLOOKUP(RC[-6],'" & wsName _
& "'!C[-7]:C[9],14,),""MM/DD/YYYY"")"
Debug.Print strFormula
'MsgBox "strFormula"
End Sub
My Sheet Name is Eg: PMCC 1 and I have Content in sheet is PMCC#01.
I would like to Convert Sheet Name into PMCC#01 with replace function.
I tried this code
temp = ws.Name
newtemp = Replace(temp,"","#0")
As result, I only get 1.
Won't you just need:
ws.Name = Replace(ws.Name, " ", "#0")
Main difference is " " instead of ""
Try:
Option Explicit
Sub test()
Dim strName As String
Dim ws As Worksheet
With ThisWorkbook
For Each ws In .Worksheets '<- Loop all sheets
With ws
strName = .Range("A1") '<- Let us assume that the new name appears in all sheets at range A1
.Name = strName '<- Change sheet name
End With
Next ws
End With
End Sub
The main issue is: you have created a variable, you have entered a value in it, coming from the sheet name, and you believe that modifying the value of that variable will automatically modify your sheet name.
This is not the way variables work: you specifically need to put your variable's value into the sheet name, something like:
temp = ws.Name
newtemp = Replacement_function(temp, ...) // not sure to use `Replace()` or `Substitute()`
ws.Name = newtemp
In case the numeric element of your worksheet name can be 10 or higher, you might want to do this:
temp = Split(ws_Name, " ")
newtemp = temp(0) & "#" & Format(temp(1), "00")
That way, PMCC 1 becomes PMCC#01 but PMCC 13 would become PMCC#13, not PMCC#013
I'm unable to use the VLOOKUP function to search a wookbook that is a variable. One that changes name by date.
So I'm new to VBA and coding in general. Having a workbook that is a variable, according to date. Doing a VLOOKUP against that seems to be an issue. By reading online, it seems it can be done as a string, but it is already a workbook.
So bear in mind i've set wkbk as a variable (I've trimmed it down for this website, the variable searches for previous dates counting backwards from current date in a workbook named dd.mm.yyyy.xlsx and that part works fine).
Dim wkbk As Workbook
ActiveCell.FormulaR1C1 = _
"=IF(ISBLANK(RC[-9]),"" "",VLOOKUP(RC[-9],'" & wkbk & "easy_form_response_list'!C1:C12,10))"
What I expected is a lookup of the workbook and sheet - what I get is a Run-time error '438'. Object doesn't support this property or method. Any ideas?
You need a string that is the fully formed and properly punctuated address to the external workbook's
Dim wkbk As Workbook, addr as string
SET wkbk = WORKBOOKS("THE_SOURCE_WORKBOOK.XLSX")
addr = wkbk.worksheets("easy_form_response_list").Range("A:L").Address(ReferenceStyle:=xlR1C1, External:=true)
ActiveCell.FormulaR1C1 = _
"=IF(ISBLANK(RC[-9]), text(,), VLOOKUP(RC[-9], " & addr & ", 10))"
Are you sure you don't need this?
ActiveCell.FormulaR1C1 = _
"=IF(ISBLANK(RC[-9]), text(,), VLOOKUP(RC[-9], " & addr & ", 10, FALSE))"
If you omit the optional fourth argument, your data needs to be sorted in an ascending manner.