Реализовал метод Крамера по решению системы уравнений. При вызове его из строки формул Excel все работает отлично, но когда я вызываю его из другой функции, то происходит ошибка... Причем сообщение об ошибке не отображается, просто на этой строчке вызывающая функция завершается (проверил через брэйкпоинты)
Крамер:
[vba]
Код
Function Kramer(A As Variant, B As Variant) As Variant
Dim i As Integer Dim j As Integer Dim k As Integer Dim ARowCount As Integer Dim BRowCount As Integer
Dim detA As Double Dim ColNo As Integer
Dim DeltaMatrix() As Double Dim res As Variant
If Application.Count(A) <> Application.CountA(A) Then MsgBox "ОШИБКА" Exit Function End If
If Application.Count(B) <> Application.CountA(B) Then MsgBox "ОШИБКА" Exit Function End If
If A.Rows.Count <> B.Rows.Count Then MsgBox "ОШИБКА" Exit Function End If
If A.Columns.Count <> A.Rows.Count Then MsgBox "ОШИБКА" Exit Function End If
If detA = 0 Then MsgBox "ОШИБКА" Exit Function End If
For i = 1 To ColNo ReDim DeltaMatrix(1 To ColNo, 1 To ColNo)
For k = 1 To ColNo For j = 1 To ColNo DeltaMatrix(k, j) = A(k, j) Next j Next k
For j = 1 To ColNo DeltaMatrix(j, i) = B(j) Next j
res(i) = Application.MDeterm(DeltaMatrix) / detA Next i
Kramer = Application.Transpose(res) End Function
[/vba]
Вызывающий метод (интерполяционный канонический полином ):
[vba]
Код
Function CanonCalc(X As Variant, Y As Variant, xcalc As Double) As Variant Dim i As Integer Dim j As Integer Dim ColNo As Integer Dim res As Double Dim Delta As Double Dim KramerResult As Variant Dim AMatr As Variant
If Application.Count(X) <> Application.CountA(X) Or Application.Count(Y) <> Application.CountA(Y) Then MsgBox "ОШИБКАГ®" Exit Function End If
If X.Columns.Count > 1 Or Y.Columns.Count > 1 Then MsgBox "ОШИБКА" Exit Function End If
If X.Rows.Count <> Y.Rows.Count Then MsgBox "ОШИБКА" Exit Function End If
ColNo = X.Rows.Count
ReDim KramerResult(1 To ColNo) ReDim AMatr(1 To ColNo, 1 To ColNo)
For i = 1 To ColNo For j = 1 To ColNo AMatr(i, j) = X(i) ^ (ColNo - j) Next j Next i
KramerResult = Kramer(AMatr, Y) 'Здесь происходит ошибка For i = 1 To ColNo res = res + KramerResult(i) * xcalc ^ (ColNo - 1 - i) Next i
CanonCalc = res End Function
[/vba]
Не могли бы вы помочь понять - почему функция работает при вызове из другой функции неправильно? Заранее благодарен, proggamer12
Здравствуйте!
Реализовал метод Крамера по решению системы уравнений. При вызове его из строки формул Excel все работает отлично, но когда я вызываю его из другой функции, то происходит ошибка... Причем сообщение об ошибке не отображается, просто на этой строчке вызывающая функция завершается (проверил через брэйкпоинты)
Крамер:
[vba]
Код
Function Kramer(A As Variant, B As Variant) As Variant
Dim i As Integer Dim j As Integer Dim k As Integer Dim ARowCount As Integer Dim BRowCount As Integer
Dim detA As Double Dim ColNo As Integer
Dim DeltaMatrix() As Double Dim res As Variant
If Application.Count(A) <> Application.CountA(A) Then MsgBox "ОШИБКА" Exit Function End If
If Application.Count(B) <> Application.CountA(B) Then MsgBox "ОШИБКА" Exit Function End If
If A.Rows.Count <> B.Rows.Count Then MsgBox "ОШИБКА" Exit Function End If
If A.Columns.Count <> A.Rows.Count Then MsgBox "ОШИБКА" Exit Function End If
If detA = 0 Then MsgBox "ОШИБКА" Exit Function End If
For i = 1 To ColNo ReDim DeltaMatrix(1 To ColNo, 1 To ColNo)
For k = 1 To ColNo For j = 1 To ColNo DeltaMatrix(k, j) = A(k, j) Next j Next k
For j = 1 To ColNo DeltaMatrix(j, i) = B(j) Next j
res(i) = Application.MDeterm(DeltaMatrix) / detA Next i
Kramer = Application.Transpose(res) End Function
[/vba]
Вызывающий метод (интерполяционный канонический полином ):
[vba]
Код
Function CanonCalc(X As Variant, Y As Variant, xcalc As Double) As Variant Dim i As Integer Dim j As Integer Dim ColNo As Integer Dim res As Double Dim Delta As Double Dim KramerResult As Variant Dim AMatr As Variant
If Application.Count(X) <> Application.CountA(X) Or Application.Count(Y) <> Application.CountA(Y) Then MsgBox "ОШИБКАГ®" Exit Function End If
If X.Columns.Count > 1 Or Y.Columns.Count > 1 Then MsgBox "ОШИБКА" Exit Function End If
If X.Rows.Count <> Y.Rows.Count Then MsgBox "ОШИБКА" Exit Function End If
ColNo = X.Rows.Count
ReDim KramerResult(1 To ColNo) ReDim AMatr(1 To ColNo, 1 To ColNo)
For i = 1 To ColNo For j = 1 To ColNo AMatr(i, j) = X(i) ^ (ColNo - j) Next j Next i
KramerResult = Kramer(AMatr, Y) 'Здесь происходит ошибка For i = 1 To ColNo res = res + KramerResult(i) * xcalc ^ (ColNo - 1 - i) Next i
CanonCalc = res End Function
[/vba]
Не могли бы вы помочь понять - почему функция работает при вызове из другой функции неправильно? Заранее благодарен, proggamer12KeyCoder
KeyCoder, у вас в коде несоответствие типов (из функции CanonCalc первым атрибутом передается массив, а в функции Kramer к нему применяется метод Rows и Columns, для которых нужен объект Range) [vba]
Код
Function Kramer(A As Variant, B As Variant) As Variant Dim i As Integer Dim j As Integer Dim k As Integer Dim ARowCount As Integer Dim BRowCount As Integer
Dim detA As Double Dim ColNo As Integer
Dim DeltaMatrix() As Double Dim res As Variant
If TypeOf A Is Range Then A = A.Value ElseIf Not IsArray(A) Then MsgBox "Не задана матрица X" Exit Function End If If TypeOf B Is Range Then B = B.Value ElseIf Not IsArray(B) Then MsgBox "Не задан вектор-столбец Y" Exit Function Else: ReDim Preserve B(UBound(B), 1) End If With Application If .Count(A) <> .CountA(A) Then MsgBox "Не все элементы матрицы X являются распознаваемыми как числа. Возможно, какой-то из элементов введен неправильно" Exit Function ElseIf .Count(B) <> .CountA(B) Then MsgBox "Не все элементы вектора-столбца Y являются распознаваемыми как числа. Возможно, какой-то из элементов введен неправильно" Exit Function ElseIf UBound(A) <> UBound(B) Then MsgBox "количество строк в векторе-столбце Y и матрице X не совпадает. Видимо, был выделен неправильный диапазон чисел" Exit Function ElseIf UBound(A, 1) <> UBound(A, 2) Then MsgBox "Матрица X не является квадратной. Вычисление определителя невозможно" Exit Function End If ColNo = UBound(A) detA = .MDeterm(A)
ReDim res(1 To ColNo)
If detA = 0 Then MsgBox "Определитель матрицы равен нулю. Метод Крамера невыполним." Exit Function End If
For i = 1 To ColNo For j = 1 To ColNo Debug.Print ("Hello world") Next j Next i
For i = 1 To ColNo ReDim DeltaMatrix(1 To ColNo, 1 To ColNo)
For k = 1 To ColNo For j = 1 To ColNo DeltaMatrix(k, j) = A(k, j) Next j Next k
For j = 1 To ColNo DeltaMatrix(j, i) = B(j, 1) Next j
res(i) = .MDeterm(DeltaMatrix) / detA Next i Kramer = .Transpose(res) End With End Function
[/vba]
KeyCoder, у вас в коде несоответствие типов (из функции CanonCalc первым атрибутом передается массив, а в функции Kramer к нему применяется метод Rows и Columns, для которых нужен объект Range) [vba]
Код
Function Kramer(A As Variant, B As Variant) As Variant Dim i As Integer Dim j As Integer Dim k As Integer Dim ARowCount As Integer Dim BRowCount As Integer
Dim detA As Double Dim ColNo As Integer
Dim DeltaMatrix() As Double Dim res As Variant
If TypeOf A Is Range Then A = A.Value ElseIf Not IsArray(A) Then MsgBox "Не задана матрица X" Exit Function End If If TypeOf B Is Range Then B = B.Value ElseIf Not IsArray(B) Then MsgBox "Не задан вектор-столбец Y" Exit Function Else: ReDim Preserve B(UBound(B), 1) End If With Application If .Count(A) <> .CountA(A) Then MsgBox "Не все элементы матрицы X являются распознаваемыми как числа. Возможно, какой-то из элементов введен неправильно" Exit Function ElseIf .Count(B) <> .CountA(B) Then MsgBox "Не все элементы вектора-столбца Y являются распознаваемыми как числа. Возможно, какой-то из элементов введен неправильно" Exit Function ElseIf UBound(A) <> UBound(B) Then MsgBox "количество строк в векторе-столбце Y и матрице X не совпадает. Видимо, был выделен неправильный диапазон чисел" Exit Function ElseIf UBound(A, 1) <> UBound(A, 2) Then MsgBox "Матрица X не является квадратной. Вычисление определителя невозможно" Exit Function End If ColNo = UBound(A) detA = .MDeterm(A)
ReDim res(1 To ColNo)
If detA = 0 Then MsgBox "Определитель матрицы равен нулю. Метод Крамера невыполним." Exit Function End If
For i = 1 To ColNo For j = 1 To ColNo Debug.Print ("Hello world") Next j Next i
For i = 1 To ColNo ReDim DeltaMatrix(1 To ColNo, 1 To ColNo)
For k = 1 To ColNo For j = 1 To ColNo DeltaMatrix(k, j) = A(k, j) Next j Next k
For j = 1 To ColNo DeltaMatrix(j, i) = B(j, 1) Next j
res(i) = .MDeterm(DeltaMatrix) / detA Next i Kramer = .Transpose(res) End With End Function