【问题标题】:Why is function returning zero?为什么函数返回零?
【发布时间】:2019-02-05 23:06:58
【问题描述】:

我有两个函数可以读取 csv 数据文件并导入二维数组。使用一个简单的宏来调用这些函数,我总是得到导入文件的正确数组大小,但 ImportCSV2Array() 函数的返回值不一致。我在即时窗口中包含了诊断语句,这些语句表明分配为返回值(即数组的维度)的函数变量在调用函数和被调用函数中都是正确的。但是,当我导入一些文件时,我得到 Return 0,我不明白为什么?请问有人能建议我缺少什么吗?

这里是调用函​​数

Public Function ImportDataLog() As Boolean

Dim headerArr() As Variant
Dim filePath As String
Dim csvret As Long

On Error Resume Next
' Open file dialog to get a test file name, including path.
filePath = Application.GetOpenFilename( _
                "Test Data Files (*.csv), *.csv", 1, _
                "Select Pressure Test File")
'Debug.Print "Selected file " & filePath

' Allocate basic array before using.
ReDim headerArr(1, 1)
csvret = 0
' Read csv file and fill array with data
Application.StatusBar = "Importing . . ."
csvret = ImportCSV2Array(filePath, headerArr)

' Here csvret and UBound(headerArr, 1) should match.
Debug.Print "Return " & csvret; " (UB) " & UBound(headerArr, 1) '!!

If csvret = 0 Then
    Application.StatusBar = "Error Importing Test Data!"
    ImportDataLog = False
    'Exit Function
End If

Debug.Print "LastRecord "; headerArr(UBound(headerArr, 1), UBound(headerArr, 2))
ImportDataLog = True
Application.StatusBar = False

End Function

csv 文件通常是 2 行“测试标题”文件或包含数千条表格式记录的“测试结果”文件。当我导入“头”文件时,输出是:-

Allocated Array 1 Rows X 37 Columns
Return 1 (UB) 1
LastRecord 50.000
True

返回值和 (UB) 值符合预期。 但是“结果”文件的输出是:-

Allocated Array 8498 Rows X 9 Columns
Return 0 (UB) 8498
LastRecord 5
True

这里我不明白为什么我得到'Return 0 (UB) 8498`?

我调用的导入函数是这样的:-

' Function for importing data from csv files to 2D array.
Public Function ImportCSV2Array(csvFileName As String, ByRef arr() As Variant) As Long

Dim row_number As Long
Dim col_Offset As Integer
Dim LineFromFile As String
Dim LineItems() As String
Dim LineNum As Long
Dim Field As Variant
Dim FileNumber As Integer

FileNumber = FreeFile
Close #FileNumber
row_number = 0
Application.Calculation = xlCalculationManual

' First pass to gauge the array dimensions required
Open csvFileName For Input As #FileNumber
Do Until EOF(FileNumber)
    Line Input #FileNumber, LineFromFile
    row_number = row_number + 1
Loop ' Until EOF(FileNumber)

If InStr(1, LineFromFile, "END") >= 1 Then
    row_number = row_number - 1
End If
LineItems = Split(LineFromFile, ",")
' ReDim tha array to fit the incoming data
ReDim arr(0 To row_number - 1, 0 To UBound(LineItems))
row_number = 0
' Diagnostic to check array sized OK
Debug.Print "Allocated Array " & UBound(arr, 1) & " Rows X " & UBound(arr, 2); " Columns"
Close #FileNumber

' Now import the data to the array line by line.
Open csvFileName For Input As #FileNumber
Do Until EOF(FileNumber)
    Line Input #FileNumber, LineFromFile
    LineItems = Split(LineFromFile, ",")

    For Each Field In LineItems
        If Field <> "" Then
            arr(row_number, col_Offset) = LineItems(col_Offset)
            col_Offset = col_Offset + 1
        End If
    Next Field
    row_number = row_number + 1
    col_Offset = 0
    LineNum = LineNum + 1
Loop ' Until EOF(FileNumber)
Close #FileNumber

' Set return value to show array's first dimension
ImportCSV2Array = UBound(arr, 1)

Application.Calculation = xlCalculationAutomatic

End Function

这两个函数似乎工作正常,即导入数据正常,但我觉得如果返回值不符合预期,我会遗漏一个错误,该错误可能在以后处理数组时很重要。请问有什么建议吗?

解决方案 随着错误捕捉问题的出现,一些文件row_number 的增量超过了UBound(arr, 1)。因此,通过一些错误检查,此解决方案有效:-

Do Until EOF(FileNumber)
    Line Input #FileNumber, LineFromFile
    LineItems = Split(LineFromFile, ",")
    If row_number > UBound(arr, 1) Or InStr(1, LineFromFile, "END") >= 1 Then
        Exit Do
    End If
    For Each Field In LineItems
        If Field <> "" Then
            arr(row_number, col_Offset) = LineItems(col_Offset)
            col_Offset = col_Offset + 1
        End If
    Next Field
    row_number = row_number + 1
    col_Offset = 0
Loop ' UnLineNumtil EOF(FileNumber)

给出预期的结果:

Return 8498 (UB) 8498
LastRecord 5
True

【问题讨论】:

  • 你错过了这个错误,因为你有On Error Resume Next。删除此行,在接下来的几个月内不要使用它。然后,您会看到错误来自哪里。
  • 谢谢@Vityata,现在我明白了,“下标超出范围”。

标签: excel vba


【解决方案1】:

错误就在这里,因为2:

Debug.Print "LastRecord "; headerArr(UBound(headerArr, 1), UBound(headerArr, 2))

因为这是数组被重新调整的唯一位置,并且它的第二维没有2

ReDim headerArr(1, 1)

VBA using ubound on a multidimensional array

【讨论】:

  • 问题是row_number 的增量超出了ImportCSV2Array Redim 中设置的UBound(arr,1),所以我需要捕获它。 HeaderArrImportCSV2Array 中的 ReDim 语句调整大小。如果我注释掉 ReDim headerArr(1, 1) 声明,它没有区别;我放那行代码只是为了提供初始分配,但这不是必需的。无论如何,谢谢。
猜你喜欢
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
相关资源
最近更新 更多