gpt4 book ai didi

excel - VBA:何时使用函数与将代码放在主子中

转载 作者:行者123 更新时间:2023-12-04 22:28:09 24 4
gpt4 key购买 nike

我正在尝试将来自不同文件的季度数据编译到单个 Excel 工作簿中的过程自动化(这需要每个季度完成)。现在我已经到了一个地步,我想知道是否应该将所有代码保留在主子程序中,或者是否应该使用函数。我真的很想听听那些使用 VBA 超过几个月的人的意见,并了解如何编写高效且可读的代码。

我的代码需要做的第一件事是获取三个与日期/日期相关的变量:

  • 当前年份,如果是第四季度数据,则为前一年
  • 根据季度,一个看起来像这样的变量:2018 年第四季度的 12.31.2018;对于 2019 年第一季度,它将是 03.31.2019。它是保存相关文件的子文件夹名称。
  • 季度,即 Q1、Q2、Q3 或 Q4。

  • 请参阅下面的代码,如果有什么引起您的注意,请改进它。具体来说,我想知道如何命名我的变量(如果你有一个存储年份的变量,你会怎么称呼它?)。此外, Case Else没必要吧?我的意思是 month(Date)只能是 12 个月之一。
    Sub DetermineDate()

    Dim qVar As String
    Dim yVar As Integer
    Dim fullDate As String

    yVar = Year(Date) 'set value here or each time in case statement?

    Select Case month(Date)
    Case 1, 2, 3
    qVar = "Q4"
    yVar = Year(Date) - 1
    fullDate = "12.31." & yVar
    Case 4, 5, 6
    qVar = "Q1"
    fullDate = "03.31." & yVar
    Case 7, 8, 9
    qVar = "Q2"
    fullDate = "06.30." & yVar
    Case 10, 11, 12
    qVar = "Q3"
    fullDate = "09.30." & yVar
    Case Else
    MsgBox "Error"
    Exit Sub

    End Select
    End Sub

    但是,我的问题是:有什么理由不把它放在主子中吗?我有这样的想法,那就是专注于主子中的代码内容(复制粘贴所有数据)会很好。所以我觉得将代码确定日期放在单独的函数中是有意义的。但是,我发现返回多个值并不简单,也不是函数的意图。另外,我只会调用这个函数一次,所以经过一番思考,我得出结论,把它放在其他地方可能没有意义。基本上我问的是使用函数和多个潜艇时什么是好的做法。

    最佳答案

    你可以做这样的事情。

    将以下代码添加到新的 类(class)模块 在 VBA 编辑器中并确保为该新类命名 cls 对象 ...

    Public Quarter As Integer
    Public Year As Integer
    Public EndDate As Date

    Property Get EndMonth() As Integer
    EndMonth = Month(EndDate)
    End Property

    Property Get QuarterText() As String
    QuarterText = "Quarter " & Quarter
    End Property

    Property Get DateString() As String
    DateString = Right("0" & EndMonth, 2) & "." & Day(EndDate) & "." & Year
    End Property

    现在,将以下代码添加到新的 模块 在 VBA 编辑器中...
    Function DetermineDate(ByVal dtDate As Date) As clsObject
    ' Initialise the current functions return value.
    ' This is only required if the return value is an object that is yet to be assigned a value
    Set DetermineDate = New clsObject

    ' If the year is a simple derivation that is not specific to the month, do it here.
    ' You can also set it here first if it is the default for the vast majority of cases
    ' and then in the case statement, set it to something different if required.
    DetermineDate.Year = Year(dtDate)

    Select Case Month(dtDate)
    Case 1, 2, 3
    DetermineDate.Quarter = 4
    DetermineDate.EndDate = DateSerial(DetermineDate.Year, 12, 31)
    DetermineDate.Year = DetermineDate.Year - 1

    Case 4, 5, 6
    DetermineDate.Quarter = 1
    DetermineDate.EndDate = DateSerial(DetermineDate.Year, 3, 31)

    Case 7, 8, 9
    DetermineDate.Quarter = 2
    DetermineDate.EndDate = DateSerial(DetermineDate.Year, 6, 30)

    Case 10, 11, 12
    DetermineDate.Quarter = 3
    DetermineDate.EndDate = DateSerial(DetermineDate.Year, 9, 30)

    Case Else
    ' For this scenario, you don't need an else but it's here anyway.
    Exit Function

    End Select
    End Function

    Public Sub CallDetermineDate()
    Dim objResult As clsObject

    Set objResult = DetermineDate(Now)

    Debug.Print "End Date = " & objResult.EndDate
    Debug.Print "Year = " & objResult.Year
    Debug.Print "End Month = " & objResult.EndMonth
    Debug.Print "Quarter = " & objResult.Quarter
    Debug.Print "Quarter Text = " & objResult.QuarterText
    Debug.Print "Date String = " & objResult.DateString
    End Sub

    ... 现在运行 CallDetermineDate例程,您将看到输出。

    无论我是否正确设置了您的逻辑都不是重点,它试图说明 VBA 中不同对象的用法以及它们如何连接在一起。

    顺便说一句 - 一个函数可以返回一个值,子不能。

    在 VBA 中通常有多种方法可以做事,有些方法比其他方法更好,但很多时候,这取决于场景以及您需要采取多远的解决方案,即边缘情况、数据集的大小、性能与可读性等。

    以上也可以通过几种不同的方式完成,尤其是DetermineDate,所有这些代码实际上都可以为类模块本身形成一个构造函数(很好的一种),而不是在模块世界中闲逛。同样,有很多方法可以做事。

    希望它可以解释自己,如果没有,请询​​问,但我希望即使只有一点点也能有所帮助。

    关于excel - VBA:何时使用函数与将代码放在主子中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55878753/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com