Notifications
Clear all

Argument not optional em Sub recursiva

4 Posts
2 Usuários
0 Reactions
940 Visualizações
(@mathiasime)
Posts: 0
New Member
Topic starter
 

Pessoal, criei uma sub interp_voltx2, bem simples na qual realizo 5 iterações pra cada uma das 13 linhas em que pego, inicialmente, o valor em P4 para deltax e, daí, calculo minha spline pela função abaixo. No entanto, ao executar a sub, recebo o "Argument not optional" sem qualquer indicação de onde o erro ocorreu.

Quando executo somente a função cubic_spline ela executa normalmente.

Já testei também, a mesma sub interp_voltx (somente sem a definição de byref deltax) em outro código de spline e executou sem problemas.

Sub interp_voltx2(ByRef deltax As Double)
Dim j, k As Integer, x As Double
Dim t As Single
t = Timer

Range("AN2:AN102").Value = Range("AA2:AA102").Value

For j = 1 To 13 'linhas
    For k = 1 To 5 'iterações
        deltax = Cells(3 + j, "P").Value
        x = cubic_spline(Range("Q24:Q32"), Range("R24:R32"), deltax)
        Cells(3 + j, "O").Value = x
    Next k
Next j

Range("AN2:AN102").Select
Selection.ClearContents
Range("a1").Select
    
MsgBox Timer - t
End Sub
Option Base 1

Function cubic_spline(input_column As Range, output_column As Range, x As Range)

Dim input_count As Integer
Dim output_count As Integer

input_count = input_column.Rows.Count
output_count = output_column.Rows.Count

If input_count <> output_count Then
    cubic_spline = "Something's messed up!  The number of indeces number of output_columnues don't match!"
    GoTo out
End If
 
ReDim xin(input_count) As Single
ReDim yin(input_count) As Single

Dim C As Integer

For C = 1 To input_count
xin(C) = input_column(C)
yin(C) = output_column(C)
Next C

Dim N As Integer 'n=input_count
Dim i, k As Integer 'these are loop counting integers
Dim p, qn, sig, un As Single
ReDim u(input_count - 1) As Single
ReDim yt(input_count) As Single 'these are the 2nd deriv values

N = input_count
yt(1) = 0
u(1) = 0

For i = 2 To N - 1
    sig = (xin(i) - xin(i - 1)) / (xin(i + 1) - xin(i - 1))
    p = sig * yt(i - 1) + 2
    yt(i) = (sig - 1) / p
    u(i) = (yin(i + 1) - yin(i)) / (xin(i + 1) - xin(i)) - (yin(i) - yin(i - 1)) / (xin(i) - xin(i - 1))
    u(i) = (6 * u(i) / (xin(i + 1) - xin(i - 1)) - sig * u(i - 1)) / p
    
    Next i
    
qn = 0
un = 0

yt(N) = (un - qn * u(N - 1)) / (qn * yt(N - 1) + 1)

For k = N - 1 To 1 Step -1
    yt(k) = yt(k) * yt(k + 1) + u(k)
Next k

Dim klo, khi As Integer
Dim h, B, A As Single

klo = 1
khi = N
Do
k = khi - klo
If xin(k) > x Then
khi = k
Else
klo = k
End If
k = khi - klo
Loop While k > 1
h = xin(khi) - xin(klo)
A = (xin(khi) - x) / h
B = (x - xin(klo)) / h
y = A * yin(klo) + B * yin(khi) + ((A ^ 3 - A) * yt(klo) + (B ^ 3 - B) * yt(khi)) * (h ^ 2) / 6


cubic_spline = y

out:
End Function

O que pode estar ocorrendo?

 
Postado : 21/10/2015 2:18 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Assim superficialmente, "o que salta aos olhos" e na função cubic_spline "e esperado" receber a variavel x como Range, porem na Sub interp_voltx2 a variavel deltax (que passa o valor para x) está definida como Double. Iguale a definição que devera "rodar".

Obs.: Na declaração Dim j, k As Integer a variavel j "assume" valor "Variant" e k integer; se deseja que ambos sejam integer a declaração deve ser:
Dim j As Integer, k As Integer

 
Postado : 22/10/2015 10:33 am
(@mathiasime)
Posts: 0
New Member
Topic starter
 

Assim superficialmente, "o que salta aos olhos" e na função cubic_spline "e esperado" receber a variavel x como Range, porem na Sub interp_voltx2 a variavel deltax (que passa o valor para x) está definida como Double. Iguale a definição que devera "rodar".

Obs.: Na declaração Dim j, k As Integer a variavel j "assume" valor "Variant" e k integer; se deseja que ambos sejam integer a declaração deve ser:
Dim j As Integer, k As Integer

Reinaldo, muito obrigado pelos comentários, acertei todos como double no entanto continuo recebendo o "Argument not optional"

O que não me faz sentido é que a função cubic_spline funciona normalmente mas quando executada pela sub, retorna a "falta de argumento" (se é que esse é o problema).

 
Postado : 22/10/2015 12:23 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Não vou nem tentar entender os calculos. Mas me diga como voce faz para "chamar" o procedimento Sub?
Como montada a sub interp... deve ser chamada via um outro procedimento e deve ser "passado" a variavel deltax.

Deveria ter uma rotina =/- assim:

Sub tt()
interp_voltx2 (0)
End Sub

Note que após o nome da sub, o parametro esperado e informado entre (); não vai influenciar em nada a rotina,pois os valores são pegos na propria sub

Testei aqui com valores aleatorios, e rodou sem problema, porem não sei se o resultado é o esperado

 
Postado : 22/10/2015 2:44 pm