我想知道我是否会出错。我开始上课并尝试在我的VBA代码中使用它们。
我创建了一个代码,用于将CSV文件导入到新创建的工作表中。 我在类中创建工作表并将文件导入到某个范围。 范围将根据导入的文件而有所不同。 理想情况下,我希望将范围引用返回到类之外的模块,并根据需要在范围内循环。
我似乎无法使用我的模块代码成功返回范围对象。 用:
' Module code '''' \/
set NewTest as new TestClass
Dim testrange As Range
test Range = NewTest.SourceRange
' Module code '''' /\
Option Explicit
Const cDirectory As String = "C:\directory" 'file path
Const cFileExt As String = ".CSV" 'file
Const cSourceCode As String = "wsSourceCode"
Private cFinalFileName As String
Private wsSourceCode As Worksheet
Private cSourcePath As String
Private pSourceRange As Range
Private LastRow As Integer
Private pSourceSheet As String
'''''''''''''''''''''''''''''''''''''''''''''''''''' Can i do this !?!?!?!? \/
Public Property Get SourceRange() As Range
LastRow = wsSourceCode.Cells(wsSourceCode.Rows.Count, "A").End(xlUp).Row
Set pSourceRange = wsSourceCode.Range("A1:A" & LastRow)
SourceRange = pSourceRange
End Property
'''''''''''''''''''''''''''''''''''''''''''''''''''' Can i do this !?!?!?!? ?|
Public Property Get SourceSheet() As String
pSourceSheet = wsSourceCode.Name
SourceSheet = pSourceSheet
End Property
Public Property Get FinalRange() As String
FinalRange = pFinalRange
End Property
Public Property Set FinalRange(Value As Range)
pFinalRange = Value
End Property
Public Property Let SourceFile(Value As String)
pSourceFile = Value
cFinalFileName = pSourceFile & "Production" & cFileExt
cSourcePath = cDirectory & pSourceFile & cFileExt
End Property
Private Sub Class_Initialize()
'Create Holding Sheet to Populate and augment Code
Application.DisplayAlerts = False
On Error Resume Next
ThisWorkbook.Sheets(cSourceCode).Delete
On Error GoTo 0
Application.DisplayAlerts = True
ActiveWorkbook.Worksheets.Add(After:=Worksheets(1)).Name = cSourceCode
Set wsSourceCode = Sheets(cSourceCode)
'WsHolding.Visible = False
End Sub
Private Sub Class_Terminate()
' Application.DisplayAlerts = False
' On Error Resume Next
' ThisWorkbook.Sheets(cSourceCode).Delete
' On Error GoTo 0
' Application.DisplayAlerts = True
End Sub
Public Sub ExportCode(ByVal pFinalRange As Range)
''''''''''''''''''''''''''''''''''''''''''''''''''''
'This Process Will import the final Range of output
'code and export it to a Output file.
' The Output file was delare earlier.
'
'
''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim fso As Object
Dim Fileout As Object
Dim myFile As String
Dim rng As Range
myFile = cOutputFile
Open myFile For Output As #1
For Each rng In pFinalRange
Print #1, rng
Next rng
Close 1
End Sub
Public Sub ImportFile(ByVal cSourceFileName As String)
''''''''''''''''''''''''''''''''''''''''''''''''''''
'This Process Will import the final Range of output
'code and export it to a Output file.
' The Output file was delare earlier.
'
'
''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim strTextLine As String
Dim cSourcePath As String
cSourcePath = cDirectory & cSourceFileName & cFileExt
Dim iFile As Integer: iFile = FreeFile
Dim i As Integer: i = 1
Open cSourcePath For Input As #iFile 'open the file
Do Until EOF(1) 'until the end of the file
Line Input #1, strTextLine 'set each line equal to variable strTextLine
wsSourceCode.Cells(i, 1).NumberFormat = "@"
wsSourceCode.Cells(i, 1) = CStr(strTextLine)
i = i + 1
Loop
Close #iFile
End Sub
答案 0 :(得分:5)
简短回答基本上是what @Comintern said.
此:
SourceRange = pSourceRange
应该是这样的:
Set SourceRange = pSourceRange
我在你的班级上运行了最新的Rubberduck 代码检查,我的小ducky(我管理的开源项目)同意:
对象变量' SourceRange'没有' Set'关键字强>
就Rubberduck而言,这个变量是一个对象变量,没有' Set'关键词。这会导致运行时错误91'对象或With块变量未设置'。
所以你问,我可以这样做吗?
当然,你可以 - 真正的问题是你是否。
你有Property Get
程序有副作用,如果星星对齐,会引发运行时错误。那不好。
Property Get
程序应该具有可预测且可重复的行为 - 它不应该设置类中的任何内容'内部状态,而不是返回一个封装在该内部私有状态中的值。
请花点时间阅读.net property design guidelines - 所有也适用于VBA属性设计(只需更换"抛出异常"使用"提升错误"。)
所以更好的 SourceRange
属性看起来像这样:
Public Property Get SourceRange() As Range
If wsSourceCode Is Nothing Then Exit Property
Dim lastRow As Long
lastRow = = wsSourceCode.Cells(wsSourceCode.Rows.Count, "A").End(xlUp).Row
Set SourceRange = wsSourceCode.Range("A1:A" & LastRow)
End Property
请注意,readonly(get-only)属性独立存在,范围是自己的局部变量,不会改变内部状态,如果Nothing
引用不是&#39则返回wsSourceCode
; t set,并且不假设工作表少于32,767行(这是Integer
变量的最大值)。
如果这是一个Code Review答案,我也说Class_Initialize
处理程序做得太多,不容易预测的事情 1 - 考虑这个用法案件; foo
和bar
有何不同?
Set foo = New TestClass
Set bar = New TestClass
'this goes boom. why?
Debug.Print foo.SourceRange.Address, bar.SourceRange.Address
1 哎呀,好吧我还是说了。