返回(私有?)范围的类

The*_*Man 1 vba class range

我想知道我是否会出错.我开始上课并尝试在我的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
Run Code Online (Sandbox Code Playgroud)

Mat*_*don 5

简短的回答基本上就是@Comintern所说的.

这个:

SourceRange = pSourceRange
Run Code Online (Sandbox Code Playgroud)

应该是这样的:

Set SourceRange = pSourceRange
Run Code Online (Sandbox Code Playgroud)

我跑了最新Rubberduck代码检查你的课,我的小鸭子(我管理该开源项目)同意:

对象变量"SourceRange"的分配没有"Set"关键字

就Rubberduck而言,这个变量是一个对象变量,没有'Set'关键字.这会导致运行时错误91'对象或With块变量未设置'.

所以你问,我可以这样做吗?

当然,你可以 - 真正的问题是你是否应该.

您有一个具有副作用Property Get过程,如果星星对齐,可能会引发运行时错误.这不好.

一个Property Get过程应该具有可预测和可重现的行为 - 它不应该在类的内部状态中设置任何东西,而应该返回一个封装在该内部私有状态中的值.

花点时间阅读.net属性设计指南 - 所有这些指南适用于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
Run Code Online (Sandbox Code Playgroud)

请注意,readonly(get-only)属性独立存在,范围是自己的局部变量,不改变内部状态,Nothing如果wsSourceCode未设置引用则返回,并且不假设工作表少于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
Run Code Online (Sandbox Code Playgroud)

1哎呀,好吧我还是说了.