У меня есть две функции для чтения файлов данных CSV и импорта в 2D-массивы.Используя простой макрос для вызова этих функций, я всегда получаю правильный размер массива для импортируемых файлов, но возвращаемое значение функции 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 обычно представляют собой двухстрочный файл «Test Header» или «Результаты теста».'файл с тысячами записей в табличном формате.Когда я импортирую файл «Заголовок», вывод: -
Allocated Array 1 Rows X 37 Columns
Return 1 (UB) 1
LastRecord 50.000
True
Return и (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