Reputation: 21
I am working on a macro involving usedrange. Basically my sub tries to open up a text file with opentext and copy the formulas in the text file and paste over to the worksheet "SOE Summary" of my destination workbook. However, a run-time error 438 would occur when I try to set the formulas of my worksheet "SOE Summary" equal to the formulas in the text file. Any insight would be appreciated.
Sub Sample()
Application.ScreenUpdating = False
Dim WB As Workbook
Set WB = ActiveWorkbook
Dim fileToOpen As Variant 'Txt file that contains formulas
Dim fileName As String _
'Name of the temporary workbook that contains formulas from fileToOpen
Dim sheetName As String _
'Name of the worksheet of the temporary workbook that contains formulas from fileToOpen
fileToOpen = Application.GetOpenFilename("Text Files (*.txt), *.txt") _
'User selects the txt file that contains formulas
If fileToOpen <> False Then 'Make sure the user selects a txt file
Workbooks.OpenText fileName:=fileToOpen, _
DataType:=xlDelimited, Tab:=True 'Transport formulas into a temporary workbook
End If
fileName = Mid(fileToOpen, InStrRev(fileToOpen, "\") + 1) _
'Name of the temporary workbook
sheetName = Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 4) _
'Name of the temporary worksheet
Application.DisplayAlerts = False 'Disable any popup windows
WB.Sheets("SOE Summary").UsedRange.Value = Workbooks(fileName).Sheets(sheetName).UsedRange.Formula_
'[ERROR 438 OCCURRED] Paste formulas into "SOE Summary" worksheet
Application.DisplayAlerts = True 'Enable popup windows after the previous line of code
Workbooks(fileName).Close savechanges:=False 'Close the temporary workbook and discard any changes
WB.Sheets("SOE Summary").UsedRange.Value = WB.Sheets("SOE Summary").UsedRange.Value _
'Replace all formulas in the "SOE Summary" worksheet with values
Application.ScreenUpdating = True
End Sub
Upvotes: 2
Views: 1038
Reputation: 71177
In VBA an instruction is terminated either by a new line, or if you want multiple instructions on a single line, by an instruction separator token (i.e. a colon :
- not that you typically want multiple instructions on a single line).
A line of code in VBA can be seen as either a logical code line, or a physical code line. When a code line gets too wide/lengthy, you can continue a logical line of code one the next physical line of code using the line continuation token (a whitespace followed by an underscore _
).
As was pointed out, most of these lines don't need to be continued - in fact, your code only compiles because the continued lines "continue" into a comment, which implicitly terminates the instruction:
fileName = Mid(fileToOpen, InStrRev(fileToOpen, "\") + 1) _ 'Name of the temporary workbook sheetName = Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 4) _
Remove these comments and your code stops compiling:
fileName = Mid(fileToOpen, InStrRev(fileToOpen, "\") + 1) _
sheetName = Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 4) _
...because you can't have two assignments in the same instruction.
So yeah, remove the extraneous line continuations, and problem solved.
The specific error you're getting is rather confusing, because UsedRange
returns an actual Range
object reference, which gives you all rights to expect a compile-time error here instead of run-time. Under the hood, this points to the Range
COM interface being extensible - meaning although most member calls are early-bound/resolved at compile-time, VBA lets you make any funky member call on a Range
object, and defers validation to run-time. Proof:
Sub Foo()
Dim bar As Range
bar.Whatever = 42 ' happily compiles
End Sub
This means you need to be especially careful for typos when doing Range
member calls, because even Option Explicit
isn't going to help you with that - in other words, use IntelliSense / auto-completion whenever referring to known members, to avoid such errors.
Since in VBA identifiers can very well end with an underscore (e.g. Formula_
), it's only at run-time that VBA queries the Range
interface and discovers that there's no such thing as a Formula_
- and boom, error 438.
Upvotes: 3
Reputation: 12113
A few things:
_
is used to indicate that a single line statement will continue on the next line. It is rarely needed and you will see below, it's actually not necessary anywhere in your subroutineUsedRange.Formula_
rather than UsedRange.Formula _
on your error line. Note the missing spacefileName
is 'Name of the temporary workbook
, for example.Sub Sample()
Application.ScreenUpdating = False
Dim WB As Workbook
Set WB = ActiveWorkbook
Dim fileToOpen As Variant
Dim fileName As String, sheetName As String
fileToOpen = Application.GetOpenFilename("Text Files (*.txt), *.txt")
If fileToOpen <> False Then
Workbooks.OpenText fileName:=fileToOpen, DataType:=xlDelimited, Tab:=True
End If
fileName = Mid(fileToOpen, InStrRev(fileToOpen, "\") + 1)
sheetName = Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 4)
Application.DisplayAlerts = False
WB.Sheets("SOE Summary").UsedRange.Value = Workbooks(fileName).Sheets(sheetName).UsedRange.Formula
Application.DisplayAlerts = True
Workbooks(fileName).Close savechanges:=False
WB.Sheets("SOE Summary").UsedRange.Value = WB.Sheets("SOE Summary").UsedRange.Value
Application.ScreenUpdating = True
End Sub
Upvotes: 2