Как использовать условие If / then для значения массива Variant / double?

#excel #vba #osisoft

#excel #vba #osisoft

Вопрос:

Я пытаюсь просмотреть каждое значение массива, сгенерированного моей функцией, и поместить его в ячейку, если значение равно <> 0, но на этом этапе я всегда получаю ошибку несоответствия типов. Код поместит значение внутри ячеек по мере его записи, но я хочу удалить значения 0 из набора и заменить на «-«.

Vals0(от 1 до 30)

 Do While (Now - 1) > fdate0
    looop0 = 1
    Start = DateAdd("n", 450, PT.Range("P2").Value)
    Endd = DateAdd("d", 1, Start)
    E0.Cells((counter0), 1).Value = fdate0

    For looop0 = 1 To 30

        vals0(looop0) = Application.Run("PIAdvCalcVal", E0Tags(looop0), Start, Endd, "average (time-weighted)", "time-weighted", "0", "1", "0")

       ' If Vals0(looop0) <> 0 Then
            E0.Cells(counter0, (looop0   1)).Value = vals0(looop0)
        'Else
         '   E0.Cells(counter0, (looop0   1)).Value = "-"
        'End If

    Next looop0


    counter0 = counter0   1
    PT.Range("P2").Value = (PT.Range("P2").Value   1)
    fdate0 = PT.Range("P2").Value

Loop
  

Вот окно locals для нескольких итераций цикла for

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

1. Вероятно, вам следует опубликовать больше кода. Какие ошибки в строке?

2. В какой строке ошибка и что говорит ошибка? Где вы определили vals0 ? Основано ли оно на 0 или на 1? (т. Е. vals0(0 to 99) Или vals0(1 to 100) — поиск функций ubound and lbound ) Является ли оно 1-мерным или более? (например vals0(1 to 100)``vals0(1 to 100, 1 to 2) )

3. Сейчас я его прокомментировал, но «Если Vals0(looop0) <> 0 Тогда» выдает ошибку несоответствия типов, это Vals0(от 1 до 30)

4. В какой vals0(looop0) момент вы получаете ошибку времени выполнения? Кстати, у вас странное соглашение об именах…

5. Когда вы обнаруживаете, что добавляете числовой суффикс к переменной, чтобы отделить ее от других переменных того же типа, но с аналогичной функцией, это обычно признак того, что вам следует использовать массивы или какую-либо другую структуру.

Ответ №1:

Вы написали: «Он говорит Variant / Double, затем, когда я захожу в массив в локальном окне, значение double отображается как vals0(1)(1) =18.2738746824382». Итак, очевидно vals0(1) , что это не double, это массив double .

К сожалению, вы нам ничего не рассказываете PIAdvCalcVal . vals0 объявляется как (одномерный) массив с 30 (?) элементами типа Variant . Это означает, что у вас есть 30 вариантов. Каждый вариант может содержать что угодно: double, строку, объект или массив чего угодно. Последнее, похоже, имеет место, PIAdvCalcVal возвращает массив двойных значений (даже если массив содержит, возможно, только одно значение).

Итак, перво-наперво: поместите оператор Debug.Print looop0, VarType(vals0(looop0)) после вашего Run -statement . Посмотрите на https://learn.microsoft.com/en-us/office/vba/Language/Reference/user-interface-help/vartype-function чтобы получить представление о числах, представляющих vartype. Если значение vartype равно something> 8192, у вас есть массив something , и это объясняет ошибку несоответствия типов — вы не можете сравнить массив с числом.

Если PIAdvCalcVal всегда возвращает массив, решением может быть просто запись If Vals0(looop0)(1) <> 0 (обратите внимание, что Vals0(looop0, 1) это не будет работать, поскольку Vals0 это не 2-мерный массив).

Более надежным решением может быть

 Var x
If IsArray(Vals0(looop0)) Then
    x = Vals0(looop0)(1)
Else
    x = Vals0(looop0)
End If
If x <> 0 Then
...
  

Наконец, вы должны проверить, насколько велик возвращаемый массив (проверьте LBound и UBound ). Что бы вы сделали, если оно содержит более одного значения?

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

1. Спасибо, я действительно новичок в этом, поэтому прошу прощения за неправильное использование терминологии. Я ценю, что вы помогаете мне решить эту проблему. piadvcalcval — это ситуация с черным ящиком, поэтому я не знаю, что это всегда будет массив.