返回(私有?)范围的类

时间:2016-09-09 13:54:30

标签: 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

1 个答案:

答案 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 - 考虑这个用法案件; foobar有何不同?

Set foo = New TestClass
Set bar = New TestClass

'this goes boom. why?
Debug.Print foo.SourceRange.Address, bar.SourceRange.Address

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