Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel VBA中的变量数据类型及其积极应用_Excel_Vba - Fatal编程技术网

Excel VBA中的变量数据类型及其积极应用

Excel VBA中的变量数据类型及其积极应用,excel,vba,Excel,Vba,谷歌上有很多关于变量数据类型的东西。大多数情况下,他们会说像“避免过多地使用它,这就是为什么”或“它可以保存任何类型的数据”,这是我理解的。但我仍然不完全明白什么时候使用它们。有人能简要地解释变量数据类型的最佳用途,更重要的是,举例说明变量数据类型的最佳用途吗(甚至可能是将变量传递给函数而不是显式声明变量的例子)?通常,总是尽可能使用最小的内存变量。Variant是最大的,所以只有在没有更好的类型时才应该使用它。这里有一些例子 数组() Array函数返回一个包含数组的变量。使用数组的唯一方法是

谷歌上有很多关于变量数据类型的东西。大多数情况下,他们会说像
“避免过多地使用它,这就是为什么”
“它可以保存任何类型的数据”
,这是我理解的。但我仍然不完全明白什么时候使用它们。有人能简要地解释变量数据类型的最佳用途,更重要的是,举例说明变量数据类型的最佳用途吗(甚至可能是将变量传递给函数而不是显式声明变量的例子)?

通常,总是尽可能使用最小的内存变量。Variant是最大的,所以只有在没有更好的类型时才应该使用它。这里有一些例子

数组()

Array
函数返回一个包含数组的变量。使用数组的唯一方法是分配给变量

vArr = Array(1, "a", True)
将数组分配给范围

如果您必须将一组数据写入单元格,那么将它们放入一个数组中并一次写入所有数据要比一次写入一个单元格快得多。如果数据都是相同的数据类型,请使用正确类型的数组。但是,如果不是所有的数据都相同,则可能需要使用一系列变体

Dim vaWrite(1 To 2, 1 To 2) As Variant

vaWrite(1, 1) = 1
vaWrite(1, 2) = "Bob"
vaWrite(2, 1) = 2
vaWrite(2, 2) = "Tim"

Range("A1").Resize(2, 2).Value = vaWrite
另一方面,从范围到数组需要一个变量,而不考虑单元格中的数据类型

vArr = Range("A1:C10").Value
工作表功能

某些(全部?)工作表函数可以返回错误,也可以返回其正常值。例如,唯一可以保存Double和Error的数据类型是Variant

vRes = Application.WorksheetFunction.Match(...)

这是我能想到的三个例子。可能会有更多的变量。

变量类型比任何其他变量占用更多的内存空间(,为了测试,我刚刚添加了变量例程)


可能还有其他一些因素在起作用,这是一个非常主观的话题,因此这是我的个人经历:
1.一个好的代码必须明确解释,使用variant可能会导致混淆应该首先定义什么。
二,。Variant可能无法获得对象的真实属性,因此,您需要花费更多的时间来编写代码,并且您可能看不到对象的真实属性,即:

Dim myRange as Range
Set myRange = Range("A1:A10")
myRange. 'I can see the properties of the object!
Dim myRange as Variant
Set myRange = Range("A1:A10")
myRange. 'I can't see what properties this may have in this context!

我想给出一个真实的背景,说明为什么要避免它们,我想我们都同意这一点。
现在,什么时候使用它们?这可能也需要讨论,但是,我发现它们在您无法控制输入时非常有用。
这将如何发生?
示例1:允许用户输入文本框值,我不想让用户键入单词,只键入数字(无论何时键入单词都会阻止它),但是,仅文本框无法阻止它,那么,您应该怎么做

Private Sub TextBox_Value_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
Dim ChrPressed As Variant
    ChrPressed = Chr(KeyAscii)
    Select Case ChrPressed
        Case IsNumeric(ChrPressed)
        Me.TextBox_Value.Value = Me.TextBox_Value.Value & ChrPressed
        KeyAscii = 0
        Case "0"
        Me.TextBox_Value.Value = Me.TextBox_Value.Value & ChrPressed
        KeyAscii = 0
    End Select
End Sub
ChrPressed是一种变体,因为用户仍然可以按word键,但我们将定义按下的内容,并在代码中进行研究-其他方法可能会导致错误调试器对用户造成影响,从而使我们的体验不那么流畅-。
二,。如果您不想添加适当的引用来避免,但是,您知道这些函数在变量本身中是允许的,这也有助于避免将来可能不得不进行的与后期、早期绑定相关的一些变通方法(尽管我没有遇到这样做的问题):


3。可以包含大量数据且希望对其进行控制的数组

Dim ArrayForTest() as Variant
Select Case ArrayForTest(ArrayElement)
Case IsNumeric(ArrayForTest(ArrayElement))
Case IsString(ArrayForTest(ArrayElement)) 'Just representative not the real way to do so

4。元素中的元素,您尚未找到正确调用它们的方法,稍后将了解这些元素,或者这些元素对与正确调用方法相关的性能没有影响

Sub Graphs_makegraph(XValues As Variant, ChartStyle...
ActiveSheet.Shapes.AddChart2(ChartTypeNumber, ChartStyle).Select
...
ActiveChart.FullSeriesCollection(1).XValues = XValues

大多数程序员不喜欢这种方法,因为你让Excel“处理事情”,一个好的编码实践是,你应该按照定义定义一切,但是,我发现excel的多功能性加快了解决方案的速度,并为我们节省了一些.class/接口,然后又返回到调用的主类,我们在编程时必须以其他方式进行调用。作为一名OT:我的意思是,如果我们想要达到这样的严格要求,我们需要进行编程,以避免编译器干扰我们的初衷

“…将变量传递给函数而不是显式声明变量的示例”

JoelSpolsky提到了其中的一种形式,但我发现通过使用变量类型参数来模拟方法重载非常有用

例如,查看将工作表添加到工作簿的宏:

Sub addSheets(wb As Workbook, ByVal wsNames As Variant)
'Adds one or more worksheets (wsNames) to a workbook (wb)

    Dim ws As Worksheet
    Dim i As Long

    If Not IsArray(wsNames) Then
        wsNames = Array(wsNames)
    End If

    For Each ws In wb.Sheets
        For i = LBound(wsNames) To UBound(wsNames)
            If ws.Name = wsNames(i) Then
                MsgBox "Error: Sheet " & wsNames(i) & " already exists in workbook"
                Stop
                Exit Sub
            End If
        Next
    Next

    For i = LBound(wsNames) To UBound(wsNames)
        Dim newWS As Worksheet
        Set newWS = wb.Worksheets.Add
        newWS.Name = wsNames(i)
    Next

End Sub
因为它将接受wsNames参数的字符串或字符串数组,所以以下两个调用都是有效的:

'Adds sheet called "TestWS1" to the active workbook
Call addSheets(ActiveWorkbook,"TestWS1")
'Adds sheets called "TestWS2" and "TestWS3" to the active workbook 
Call addSheets(ActiveWorkbook, Array("TestWS2","TestWS3"))

通过使用变体和“IsArray”方法(以及类似的方法,如“IsNumeric”、“IsDate”等)强制单个方法为单个参数接受多个数据类型,可以避免必须创建单独的方法来完成类似任务(即“addSheet”用于添加一个WS,“addSheets”用于添加多个WS).

我做了7年的全职VB6程序员,有意识地决定使用变体的次数正好是0。古怪的行为和保存任何东西的神奇能力的缺点远远超过了您可能编写的任何聪明代码,这将使下一个维护代码的工作成为一场噩梦。
'Adds sheet called "TestWS1" to the active workbook
Call addSheets(ActiveWorkbook,"TestWS1")
'Adds sheets called "TestWS2" and "TestWS3" to the active workbook 
Call addSheets(ActiveWorkbook, Array("TestWS2","TestWS3"))