2013-06-24 2 views
0

Я работаю над функцией vba для вычисления максимального значения диапазона данных, деленного на другое. Кажется, что все работает хорошо, но проблема, похоже, существует при попытке применить Application.Max к массиву, где я обошел его, выполняя цикл. Однако я не могу вспомнить значение Max вне цикла ... Первая версия Debug.Print обычно печатает значение MaxV, однако вторая [вне цикла] Debug.Print MaxV ничего не привела. Функция CalDS2 получает значение #VALUE! ошибка.Функция VBA - Невозможно вывести переменную

Function CalDS2(RangeD As Range, RangeS As Range, MaxMin As String) As Variant  
Dim i As Integer 
Dim ArrayDS() As Variant 
Dim MaxV As Variant 
Dim MinV As Variant 
MaxV = 0 
MinV = 1000000000 
For i = 1 To RangeD.Columns.Count 
    ArrayDS(i) = Round(RangeD.Cells(1, i)/RangeS.Cells(1, i), 4) 
    If ArrayDS(i) >= MaxV Then 
     MaxV = ArrayDS(i) 
     Debug.Print MaxV 
    End If 
Next i 
Debug.Print MaxV 
CalDS2 = MaxV 
End Function 

Любая помощь будет высоко ценится, Энди

** * ***Новый код* ** * *

Function CalDS2(RangeD As Range, RangeS As Range, MaxMin As String) As Variant 
    Dim i As Long 
    Dim ArrayD, ArrayS, ArrayDS() As Variant 
    If UCase(MaxMin) <> "MAXIMUM" And UCase(MaxMin) <> "MINIMUM" Then 
     MsgBox "The 3rd argument - MaxMin - must be either Maximun or Mininum" 
     CalDS2 = "Error" 
     Exit Function 
    End If 

    ReDim ArrayDS(1 To RangeD.Columns.Count) 
    ArrayD = RangeD.Value 
    ArrayS = RangeS.Value 
    For i = 1 To RangeD.Columns.Count 
     ArrayDS(i) = ArrayD(1, i)/ArrayS(1, i) 
     Debug.Print ArrayDS(i) 
    Next i 

    If UCase(MaxMin) = "MAXIMUM" Then 
     CalDS2 = WorksheetFunction.Max(ArrayDS) 
    Else 
     CalDS2 = WorksheetFunction.Min(ArrayDS) 
    End If 
End Function 
+0

объявить MaxV в функции. 'dim MaxV как десятичное значение. попробуйте это первым. Другой вопрос: почему вы используете 'ArrayDS (i)'? – Hiten004

+0

@ Hiten004 Прямо сейчас я использую 'Dim MaxV как double', тоже попробовал' вариант', но это то же самое. Для 'ArrayDS (i)', он был там с самого начала, где я пытался сделать «Application.Max (ArrayDS)». –

+0

Я бы «ArrayDS (i)» заменил массив переменной «Dim yourvariable as double», а затем попробуйте. – Hiten004

ответ

0

Попробуйте это:

Public Enum Op 
    Minimum = 1 
    Maximum = 2 
End Enum 

' Call by "=CalDS2(B2:F2,B3:F3,2)" 
Public Function CalDS2(r_D As Range, r_S As Range, MinMax As Op) As Double 

    Dim x_D() As Variant, x_S() As Variant, x_DS() As Variant 

    x_D = r_D.Value2 
    x_S = r_S.Value2 

    Dim i As Integer, N As Integer, res As Double 

    N = r_D.Columns.Count 
    ReDim x_DS(1 To N) 

    For i = 1 To N 
     x_DS(i) = x_D(1, i)/x_S(1, i) 
    Next i 

    res = x_DS(1) 

    For i = 2 To N 
     If (MinMax = Maximum And x_DS(i) > res) _ 
     Or (MinMax = Minimum And x_DS(i) < res) Then 
      res = x_DS(i) 
     End If 
    Next i 

    CalDS2 = res 
End Function 

Это гораздо быстрее, вызывая встроенные функции, и вы читаете все значения с одним махом в x_D и x_S массивов.