Este fórum está sendo desativado

Depois de 9 anos, este fórum será desativado. Mas calma.... estamos migrando para uma comunidade no DISCORD. Junte-se a nós.

ENTRAR PARA DISCORD

Tópicos relacionados a códigos VBA, gravação de macros, etc.
  • Avatar do usuário
Por IgorAM
#48041
Ola pessoal, estou começando agora a usar VBA por isso estou com algumas dificuldades. Estou tentando criar um código que faça um processo iterativo para mim. O processo consiste em fazer o cálculo das seguintes equações na ordem a seguir:

Re = 25400v
f = 0,02
f(v) = -186,2 + 1030,16/v - 24,453fv² - v²

A intenção é que o código teste diferentes valores de v até que a função f(v) seja igual a 0.

Escrevi o código da seguinte forma:
Código: Selecionar todos
Private Sub CommandButton1_Click()

Dim v As Integer
Dim Re As Integer
Dim f As Integer
Dim funcao As Integer
Dim W As Worksheet

Set W = Sheets("Plan1")

W.Select
v = 0.1
W.Range("D2").Select

Do While ActiveCell.Value <> 0

Re = 25400 * v
f = 0.02
funcao = -186.2 + 1030.16 / v - 24.453 * f * v ^ 2 - v ^ 2
v = v + 0.1

Loop

W.Range("A2").Value = v
W.Range("B2").Value = Re
W.Range("C2").Value = f
W.Range("D2").Value = funcao


End Sub
Coloquei pra depurar e ele nem está passando pelo loop, se puderem me ajudar, agradeço!
Avatar do usuário
Por Jimmy
Avatar
#48047
Olá Igor,

Algumas considerações:

a) Para saber o porque da rotina não entrar no loop, precisaria da planilha, pois o valor da célula D2 é que define a parada ou não do loop. Acredito que na planilha ela esteja zerada, logo, se o loop vai acontecer ENQUANTO D2 é diferente de zero, nem vai entrar no loop.

b) Você deveria adotar como critério de parada a variável FUNCAO. Não pare quando ela for zero, porque pode ser que nunca seja. Defina uma faixa de erro admissível, e pare quando atingir essa faixa. Ex:, DO WHILE ABS(FUNCAO) < 0,01. Um detalhe: se a função retorna valores no domínio dos números reais, a variável funcao não pode ser definida como inteiro. Se v, inicia com 0,1 e incrementa de 0,1 em 0,1, também não pode ser um inteiro. Se f vale 0,02, idem. É melhor deixar as variáveis sem definição, por enquanto.

c) não entendi a razão da variável RE

d) O método que está utilizando para obter as raizes é horrível, e pode ser que nunca atinja o resultado. Você inicia com V=0,1, e depois vai somando 0,1. Pode ser que esse passo (0,1) seja muito grande para gerar um erro de 0,01 (do exemplo acima). Pode ser que as raizes da equação sejam ambas negativas, logo, cada vez que somar 0,1, estará se afastando das raizes. Pode ser que a raiz mais próxima seja 654 mil, logo, vai demorar um bocado pra chegar lá indo no passo de 0,1 em 0,1.

e) o método da dicotomia é mais simples, muito mais eficiente que este seu, mas ineficiente se comparado com outros. Você define um intervalo onde está pelo menos uma das raizes. Digamos 0 e 100, e calcula f(0) e f(100). Ai calcula o ponto médio (no caso, 50) e calcula f(50). Se o sinal de f(0) for diferente do sinal de f(50) (um negativo e outro positivo) significa que a raiz está entre zero e 50, pois de um lado da raiz a curva está do lado oposto do que está do outro lado. Nesse caso, você mantem o zero e 50 passa a ocupar o lugar do 100. Assim, o intervalo agora é 0 a 50. Calcula novamente o ponto médio, calcula seu f, e verifica novamente os sinais. Se entre 0 e 25 o sinal for o mesmo, significa que a raiz está entre 25 e 50. Assim, o 25 assume o lugar do zero, e o intervalo passa a ser 25-50. Vai repetindo o processo, que vai estreitando o intervalo ao redor da raiz. Quando o intervalo estiver abaixo de uma certa precisão que você definiu, pode parar o processo. O ruim desse método é que você tem que saber qual o intervalo inicial que contém a raiz, ou seja, descobrir 2 valores que gerem sinais diferentes quando jogados na função.

f) há um método mais eficiente chamado Newton-Raphson, muito mais eficiente que a dicotomia, e que exige apenas um número qualquer como início. Fixa o número 100, por exemplo, e manda rodar que ele acha a raiz com muito menos iterações. Você vai precisar da função (normalmente nominada por f(x), que você já tem, e da primeira derivada da função, nominada f'(x) (tem uma linha após o f, e diz-se "efe linha de x". No seu caso a primeira derivada é
funcao = - 1030.16 / v^2 - 24.453 * f * 2 * v - 2 * v

g) procure por outros métodos no google, procurando por "raizes funções cálculo numérico" ou "raizes funções método iterativo"

Teste a rotina abaixo
Código: Selecionar todos
Private Sub CommandButton1_Click()

Set W = Sheets("Plan1")

W.Select
funcao = 2E+22
Re = 25400 * v
f = 0.02
passo = 0.0001
v = passo

For Ciclos = 1 To 10000000
    funcao = -186.2 + 1030.16 / v - 24.453 * f * v ^ 2 - v ^ 2
    v = v + passo
    If Abs(funcao) < 0.1 Then Exit For
Next

W.Range("A2").Value = v
W.Range("B2").Value = Re
W.Range("C2").Value = f
W.Range("D2").Value = funcao
W.Range("E2").Value = Ciclos

End Sub
Note que eu substitui o DO pelo FOR, porque o DO pode entrar em loop eterno e até travar o Excel, enquanto que o FOR tem quantidade de ciclos limitado; pode demorar dependendo do valor limite, mas uma hora termina. Aumente o valor limite, se achar necessário.

Se esta mensagem colabora para a solução do problema, peço que dê um Like, clicando no botão com o "positivo", acima e a direita.

Jimmy San Juan
Por osvaldomp
#48065
IgorAM escreveu: Coloquei pra depurar e ele nem está passando pelo loop, se puderem me ajudar, agradeço!
1. não passa pelo Loop porque você declarou v como Integer e atribuiu a essa variável o valor 0,1, e aí a variável assume o valor zero que é a parte inteira do valor a ela atribuído, e como na equação "funcao" a variável v entra no denominador provoca erro de #DIV/0.
Declare v como Double. Idem, para as demais variáveis numéricas.

2. o seu Loop não faz sentido pois ele é baseado no valor contido em D2 e esse valor permanece inalterado na execução do Loop. Assim, se D2=0 o Loop não inicia, se D2<>0 o Loop será interminável.

dica - não utilize Select nos seus códigos.
long long title how many chars? lets see 123 ok more? yes 60

We have created lots of YouTube videos just so you can achieve [...]

Another post test yes yes yes or no, maybe ni? :-/

The best flat phpBB theme around. Period. Fine craftmanship and [...]

Do you need a super MOD? Well here it is. chew on this

All you need is right here. Content tag, SEO, listing, Pizza and spaghetti [...]

Lasagna on me this time ok? I got plenty of cash

this should be fantastic. but what about links,images, bbcodes etc etc? [...]

Estamos migrando para uma comunidade no Discord