Использование UBound для массива - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть переменная, объявленная как Variant в моем коде

Dim All_WorkWeeks_Entered As Variant

И я присваиваю значения, как показано ниже

With Worksheets("workweeks")
    All_WorkWeeks_Entered = Application.Transpose(.Range(.Range("A1"), .Cells(.Rows.Count, "A").End(xlUp)))
End With

Если в моем столбце «А» есть только один элемент, тоmy All_WorkWeeks_Entered будет строкой.

и в дальнейшей части кода, который я использую

For Counter = 1 To UBound(All_WorkWeeks_Entered)

Next Counter

UBound не может использоваться для строки.Как я всегда буду принимать All_WorkWeeks_Entered в качестве массива?

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Действительно, массив с одним членом представлен как его тип, а не как массив.Хороший обходной путь - проверить массив с помощью функции IsArray() и действовать соответственно.

Public Sub TestMe()

    Dim alldata As Variant    
    With Worksheets(1)
        'works ok, returning array:
        'alldata = Application.Transpose(.Range("A1:A2"))

        'problematic - does not return an array, but a type not supporting Ubound():
        alldata = Application.Transpose(.Range("A1"))
    End With

    If IsArray(alldata) Then
        Debug.Print UBound(alldata)
    Else
        Debug.Print "Single member array!"
    End If

End Sub

В этом случае можно использовать некоторую логику для возврата массива из одного члена:

If IsArray(alldata) Then
    Debug.Print UBound(alldata)
Else
    Debug.Print "Single member array!"
    ReDim alldata(1)
    alldata(1) = Application.Transpose(Worksheets(1).Range("A1"))
    Debug.Print UBound(alldata)
End If
0 голосов
/ 14 февраля 2019

Проблема в том, что Range.Value может быть либо одним Variant, либо Array of Variants, поэтому вы должны переходить при чтении значения следующим образом:

With Worksheets("workweeks")
    Dim rngTarget As Range: Set rngTarget = .Range(.Range("A1"), .Cells(.Rows.Count, "A").End(xlUp))
    If IsArray(rngTarget.Value) Then
        All_WorkWeeks_Entered = Application.Transpose(rngTarget.Value)
    Else
        Dim varArray(1 To 1) As Variant: varArray(1) = rngTarget.Value
        All_WorkWeeks_Entered = varArray
    End If
End With

И второй цикл будет выглядеть лучшекак это:

For Counter = LBound(All_WorkWeeks_Entered) To UBound(All_WorkWeeks_Entered)
' ...
Next Counter
0 голосов
/ 14 февраля 2019

Если вы транспонируете, вы получите массив, начинающийся с нуля, а не массив с одним основанием.Избавьте себя от горя, придерживаясь нижней и верхней границ для итерации цикла.

Простая проверка строки покажет вам, есть ли в столбце А более одного имени рабочего листа.значение, Разделите на недопустимый символ имени листа, и вы получите массив из одного элемента.

Dim All_WorkWeeks_Entered As Variant, counter as long

With Worksheets("workweeks")
    if .Cells(.Rows.Count, "A").End(xlUp).row>1 then
        All_WorkWeeks_Entered = Application.Transpose(.Range(.cells(1, "A"), .Cells(.Rows.Count, "A").End(xlUp)))
    else
        All_WorkWeeks_Entered = split(.Range("A1"), "/")
    end if
End With

For Counter = LBound(All_WorkWeeks_Entered) To UBound(All_WorkWeeks_Entered)
    'do stuff with All_WorkWeeks_Entered(Counter)
Next Counter
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...