Потеря ссылки на назначенный массив — Индекс вне диапазона

#arrays #vba #powerpoint

Вопрос:

У меня есть массив, объявленный в моем основном классе (модуль VBA). тем не менее, я пытаюсь вызвать функцию, которая, по сути, считывает лист Excel, ищет конкретное определение таблицы на определенном листе и возвращает массив, заполненный содержимым таблицы Excel.

Моя функция, похоже, не хочет обновлять определенный массив. пожалуйста, помогите. будет ли передача определенного массива в качестве ввода функции работать лучше?

код ниже:

 ' -----   main Module  ----

'declare my Array
Dim MyArr() As Variant

Call ReadXLFileIntoArray(excelFileAddress, excelFileSheet)

Debug.Print (MyArr(1, 1))  ' raises Subscript out of range error

'- Excel Data Processing Module

Function ReadXLFileIntoArray(addr As String, sheet As Integer)
    Dim xls     As Excel.Application
    Dim wkb     As Excel.Workbook
    Dim wks     As Excel.worksheet

    Set xls = New Excel.Application
    Set wkb = xls.Workbooks.Open(addr, ReadOnly:=True)
    Set wks = wkb.Worksheets(sheet)

    Call pushToArray(xls, wks, "excelTableName", MyArr)

    wkb.Close True
    Set wks = Nothing
    Set wkb = Nothing
    xls.Quit
    Set xls = Nothing
End Function

Function pushToArray(ByRef XL As Object, ByRef wks As worksheet, tableName As String, ByRef Arr As Variant)
Dim tmpArr As Variant
Dim x As Integer, y As Integer
r = wks.ListObjects(tableName).DataBodyRange.Rows.Count - 1
c = wks.ListObjects(tableName).DataBodyRange.Columns.Count - 1

    'ReDim Arr(c, r)  ' do i need to call this?
    tmpArr = wks.ListObjects(tableName).DataBodyRange.Value
    Set Arr = XL.Transpose(tmpArr)
    Debug.Print ("Loaded from Excel: " amp; " Records: " amp; wks.ListObjects(tableName).DataBodyRange.Rows.Count amp; "" amp; tableName)

    Debug.Print (Arr(1, 1))  ' works!

End Function
 

Комментарии:

1. Dim MyArr() As Variant Объявлено в a Sub или это переменная уровня модуля? Похоже, что вы не объявили все свои переменные, поэтому, пожалуйста, вставьте Option Explicit их в верхней части вашего модуля(модулей).

2. Вы не можете иметь Call ReadXLFileIntoArray(excelFileAddress, excelFileSheet) вне метода, так где же это? Однако ваша функция должна возвращать массив, а не заполнять глобальную переменную. Это один из способов внести ошибки в ваш процесс.

Ответ №1:

Я бы устроил это скорее так:

 ' -----   main Module  ----
Sub Tester()
    Dim MyArr As Variant, excelFileAddress As String, excelFileSheet As Long
    '...
    '...
    MyArr = ReadXLListIntoArray(excelFileAddress, excelFileSheet, "excelTableName")
    Debug.Print MyArr(1, 1)
End Sub


'- Excel Data Processing Module
Function ReadXLListIntoArray(addr As String, sheet As Long, listName As String)
    Dim xls     As Excel.Application
    Dim wkb     As Excel.Workbook
    
    Set xls = New Excel.Application
    Set wkb = xls.Workbooks.Open(addr, ReadOnly:=True)
    
    ReadXLListIntoArray = wkb.Worksheets(sheet).ListObjects(listName).DataBodyRange.Value

    wkb.Close False
    xls.Quit
End Function
 

Не уверен, нужно ли вам это Transpose или нет…

Комментарии:

1. это хорошо. моя единственная проблема, которую я хотел бы решить, заключается в том, что будет несколько таблиц, которые я буду читать и назначать нескольким массивам… это означает, что для ссылок на объекты excel потребуются ресурсы

2. В этом случае вам нужно будет по — другому структурировать свой код-я просто следовал вашему примеру…

3. Все хорошо! заставил его работать, используя явное объявление на странице и возвращая вариант из функции