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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.