子和函数之间的区别:"return a value"是什么意思?



我是一个VBA(以及一般编程)专家。我试图理解VBA中子程序和函数之间的根本区别。我读过各种各样的网站/书籍,但没有一本能清楚地说明这些概念是什么以及它们之间的区别。

特别是,我看到到处都有这样的解释:;子执行任务但不返回值"0";但是";函数返回要执行的任务的值";。

嗯。。。因此,假设我编写了一个函数,它从Excel中的一个单元格中获取一个(数值)值,并返回该值的两倍(在另一个单元格)。我也可以写一个做同样事情的子:读取一个单元格的值,然后打印该值的两倍。那么,为什么它说sub不返回值,而它显然返回了值呢?!

请帮我理解这一点。

"返回";与";打印";。打印是向用户显示结果的过程;一般来说,程序不能使用打印值。另一方面,返回值是为了进一步处理;用户不能直接访问它。

与现实世界相比:子程序就像一个执行某个动作的命令;函数就像一个问题,给你一个可以进一步询问的答案。

想象一下,你是一家建筑公司的工头,但你讨厌离开办公室"在南墙上安装一扇窗户";是一个命令——一个子例程。一个工人出去做这件事;拍一张大楼的照片,并把它展示给客户;。工头没有从中得到任何信息(除了确认工人已经完成了你的要求)。

另一方面;大楼旁边的树有多高&"还有水泥吗&"询问客户关于这张照片的情况,并告诉我他的评论是什么;所有人都给工头一个答案,工头可以据此做出进一步的决定。这就是职能。

如果您有一个函数AreaOfRectangle可以计算宽度乘以高度,那么您也可以有一个功能AreaOfRectangularBox,它向AreaOfRectangle询问长方体的前、左和顶面的面积,将它们分别加倍(因为后、右和底面相同),然后将它们相加,返回矩形长方体的面积。用户仍然不知道这个数字是多少,但程序知道。

如果你有一个子程序AreaOfRectangle,它显示屏幕上的宽度乘以高度,你就不能在程序的其余部分使用这些知识,因为AreaOfRectangle不会向程序返回任何信息(除了它是用它正在做的事情来完成的)。


在一些编程语言中,子例程有能力修改它们的参数,因此它并不是一成不变的,但仍然是"返回";(到呼叫代码)和";打印";(对用户)保持相关性。此外,在某些语言中,子例程甚至不必报告它们何时完成(这些被称为"异步");但这也是稍后要讨论的细节。

编辑:

返回值的两倍(在另一个单元格中)

类似Range("A2").Value = Range("A1").Value * 2的东西不是";返回";。这是命令程序将值存储在单元格中——概念上接近子程序(在某些语言中,它可能是一个子例程——类似于SetAt(X, Y, Val)——尽管VBA使用对.Value属性的赋值)。程序稍后可以查询该单元格中的值——概念上接近函数(在某些语言中,它实际上可能是一个函数——类似于Val = GetAt(X, Y)——尽管VBA使用对.Value属性的简单访问)。

如果在单元格中的公式中使用函数的返回值,比如=DoubleThis(5),那么这实际上是正确的返回。但至关重要的是,这是一个公式,所以基本上它仍然在代码的领域,而不是用户的领域。您也可以写入=DoubleThis(5)+7,并且10的返回值将用于与7相加,以获得17的总结果。(然后Excel接管并显示单元格值;但这不再是您的代码。)

有时人们使用这个词有点随意;但如果你在学习编程,你必须严格区分这两种场景。

子与函数

  • 请注意,以下尝试描述子函数和函数之间的差异时存在不准确和信息缺失

Sub

  • 下面是一个简单的过程,返回B1A1值的两倍
Sub sDoubleSimple()
Range("B1").Value = 2 * Range("A1").Value
End Sub
  • 要将其用于所选单元格,可以添加两个参数并重写过程:
Sub sDouble(ByVal SourceCell As Range, ByVal DestinationCell As Range)
DestinationCell.Value = 2 * SourceCell.Value
End Sub
  • 要使用它,您可以通过以下方式调用它:
Sub sExamples()

sDouble Range("A1"), Range("B1")

sDouble Range("A2"), Range("B2")
Dim sCell As Range
For Each sCell In Range("A3:A10").Cells
sDouble2 Cells(sCell.Row, "B"), sCell
Next sCell
End Sub
  • 基本上,它返回的值是列B中列A的值的的两倍
  • 请注意,我在前面相当不准确的描述中使用的返回不是与函数相关的返回

功能

  • 要"将最后一个子函数重写为函数",您可以执行
Function fDouble(ByVal SourceCell As Range) As Double
fDouble = 2 * SourceCell.Value
End Function

并像这样使用它:

Sub fExamples()

Range("B1").Value = fDouble(Range("A1"))

Range("B2").Value = fDouble(Range("A2"))

Dim sCell As Range
For Each sCell In Range("A3:A10").Cells
Cells(sCell.Row, "B").Value = fDouble(sCell)
Next sCell

End Sub
  • 乍一看,除了语法之外,"子方法和函数方法"之间似乎没有区别。他们实际上也做了同样的事情,但有很大的不同,比如看线。。。

    Range("B1").Value = fDouble(Range("A1"))
    

    我们可以看到fDouble(Range("A1"))将被写入Range("B1"),因此我们可以得出结论,前者必须是函数的返回值的数字,即我们可以以各种方式使用它,在消息框中返回它。。。

Sub fExamplesMsg()

MsgBox fDouble(Range("A1"))

MsgBox fDouble(Range("A2"))

Dim sCell As Range
For Each sCell In Range("A3:A10").Cells
MsgBox fDouble(sCell)
Next sCell
End Sub

或在"立即"窗口中(Ctrl+G)。。。

Sub fExamplesPrint()

Debug.Print fDouble(Range("A1"))

Debug.Print fDouble(Range("A2"))

Dim sCell As Range
For Each sCell In Range("A3:A10").Cells
Debug.Print fDouble(sCell)
Next sCell
End Sub
  • 最重要的是,我们可以将return值写入变量,例如在If语句中使用它来进一步选择单元格中将返回的
Sub fExamplesConditional()

Dim cValue As Double

cValue = fDouble(Range("A1"))
If cValue > 50 Then
Range("B1").Value = cValue
End If

cValue = fDouble(Range("A2"))
If cValue > 50 Then
Range("B2").Value = cValue
End If

Dim sCell As Range
For Each sCell In Range("A3:A10").Cells
cValue = fDouble(sCell.Value)
If cValue > 50 Then
Cells(sCell.Row, "B").Value = cValue
End If
Next sCell

End Sub
  • 基本上,如果结果大于50,它将返回两倍于B列中A列值的

结论

  • 您可以说子执行,而函数返回。函数将在调用过程中返回一个值,您可以在该过程中进一步操作它。想想所有Excel函数,它们都返回结果。它们不会将结果写入另一个单元格,而是写入该单元格,例如,在单元格B1中,可以使用=fDouble(A1)

相关内容

  • 没有找到相关文章