Notifications
Clear all

Função Matricial

8 Posts
2 Usuários
0 Reactions
1,175 Visualizações
(@golfinhu)
Posts: 4
New Member
Topic starter
 

~Galera, como vai, tudo bem?

Tenho uma planilha com vários ângulos em grau minuto e segundo, e, em uma parte dela, preciso do somatório destes ângulos!
Para convertê-lo em Decimais estou usando o seguinte código:

Function Convert_Decimal(Degree_Deg) As Variant
    'Declaração das variáveis.
    Dim degrees As Double
    Dim minutes As Double
    Dim seconds As Double
    Dim reg As Object

    'Inicia o módulo de expressões regulares.
    Set reg = CreateObject("vbscript.regexp")

    'Indico o teste que a expressão regular deverá fazer.
    reg.Pattern = "[0-9]+° [0-9]+' [0-9.,]+" & Chr(34)
    
    
    If reg.test(Degree_Deg) = False Then
        Convert_Decimal = "Format Error"
        Exit Function
    End If
    
    'Substituo vírgula por ponto.
    Degree_Deg = Replace(Degree_Deg, ",", ".")
    
    'Obtenho o valor dos graus.
    degrees = Val(Left(Degree_Deg, InStr(1, Degree_Deg, "°") - 1))
    
    'Obtenho o valor dos minutos
    minutes = Val(Mid(Degree_Deg, InStr(1, Degree_Deg, "°") + 2, _
                 InStr(1, Degree_Deg, "'") - InStr(1, Degree_Deg, _
                 "°") - 2)) / 60
     
     'Obtenho o valor dos segundos
     seconds = Val(Mid(Degree_Deg, InStr(1, Degree_Deg, "'") + _
                2, Len(Degree_Deg) - InStr(1, Degree_Deg, "'") - 2)) _
                / 3600
    Convert_Decimal = degrees + minutes + seconds
End Function

Convertendo cada um individualmente funciona normal, mas, eu gostaria da somatória total destes valores e por isso estou tentando usar função matricial:

{=SOMA(Convert_Decimal(C3:C12))}

Que, ao meu entender, ele deveria converter cada célula individualmente em decimal e depois fazer o somatório, no entanto, fico recebendo o erro #Valor...

Utilizando uma função matricial para somar os valores absolutos de um intervalo de células, por exemplo:

{=SOMA(ABS(C3:C12))}

Funciona normalmente...

Eu consigo fazer estes cálculos usando uma coluna auxiliar, porém, eu gostaria de fazê-lo sem esta coluna!

Será que alguém poderia me ajudar?

Muito obrigado!

 
Postado : 21/03/2016 1:04 pm
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Experimente

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 21/03/2016 1:28 pm
(@golfinhu)
Posts: 4
New Member
Topic starter
 

Olá, Reinaldo, muito obrigado pela resposta rápida!

Usando a função do VBA que se encontra dentro das macros, a SomaGrau, realmente funciona e já me ajuda neste projeto, porém, eu gostaria de saber o porquê eu não consigo usar a função que eu estava usando no modo matricial, como deve estar o código VBA para que este aceite funções matriciais, sabe me explicar? Muito obrigado mais uma vez!

 
Postado : 21/03/2016 1:45 pm
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Usando a solução proposta pelo Reinaldo *(e portanto o crédito é dele):

=SOMA(ESQUERDA(C3:C12;LOCALIZAR("º";C3:C12;1)-1)+(EXT.TEXTO(C3:C12;LOCALIZAR("º";C3:C12;1)+1;2)/60)+(EXT.TEXTO(C3:C12;LOCALIZAR("'";C3:C12;1)+1;2)/3600))

<Ctrl>+<Shift>+<Enter>

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 21/03/2016 1:57 pm
(@golfinhu)
Posts: 4
New Member
Topic starter
 

Usando a solução proposta pelo Reinaldo *(e portanto o crédito é dele):

=SOMA(ESQUERDA(C3:C12;LOCALIZAR("º";C3:C12;1)-1)+(EXT.TEXTO(C3:C12;LOCALIZAR("º";C3:C12;1)+1;2)/60)+(EXT.TEXTO(C3:C12;LOCALIZAR("'";C3:C12;1)+1;2)/3600))

<Ctrl>+<Shift>+<Enter>

Fernando, Perfeito, assim funciona perfeitamente, mas, saberia me dizer por que não funciona usando a função do VBA?

No caso da planilha que o Reinaldo postou, por que eu não consigo utilizar simplesmente:

=SOMA(GrauParaDecimal(A27:A29))

<Ctrl>+<Shift>+<Enter>

Existe algum parâmetro específico na função do VBA para que eu consiga utilizar da maneira acima descrita?

Muito obrigado novamente!

 
Postado : 21/03/2016 4:51 pm
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

#Golfinhu, logo EU que tenho uma tara incomum e até estranha por matrizes (rsrs), quando percebi que eu não sabia fazer isso (UDF Matricial), fui dar uma pesquisada e aprendi uma nova hoje, que é, como escrever uma UDF que funcione matricialmente. MUITO OBRIGADO por ter feito essa pergunta. Vamos lá!

O problema é que a função não está escrita considerando possibilidade de receber uma matriz como parâmetro ou devolver uma matriz como resultado. E esta adaptação é comigo mesmo! Foi relativamente fácil.

Escrevi de um jeito completo, à prova de erros e que funciona tanto matricialmente quanto não matricialmente com um texto como parâmetro, e com tratamento de erro caso o valor não seja um grau válido ou existam células vazias no meio!

Nota importante que eu só descobri depois de fazer: PODE USAR com <Enter> ou com <Ctrl>+<Shift>+<Enter> não faz diferença!

Exemplos de uso *(matriciais ou não):

=GrauParaDecimal("30º15'22"",0") 
=GrauParaDecimal(A27) 
=SOMA(GrauParaDecimal(A27:A29)) 
=SOMA(GrauParaDecimal(C3:C12)) 
=SOMA(GrauParaDecimal(A25:A30))

O novo código da UDF será esse, e dessa vez, os créditos são meus, rs, desculpe Reinaldão !

Option Explicit

Public Function GrauParaDecimal(Parametro As Variant) As Variant
'Autor:.....Fernando Fernandes
'Forum:.....Planilhando
'Contato:...fernando.fernandes@outlook.com.br
On Error GoTo DeuErro
Dim Intervalo       As Excel.Range
Dim Celula          As Excel.Range
Dim Coordenada      As String
Dim Grau2Decimal    As Double
Dim Grau            As Integer
Dim Minuto          As Integer
Dim Segundo         As Integer
Dim Centesimo       As Integer
Dim mtzEntrada      As Variant
Dim mtzSaida        As Variant
Dim i               As Long
Dim j               As Long

    If VBA.TypeName(Parametro) = "String" Then
Texto:
        Coordenada = VBA.CStr(Parametro)
        Grau = VBA.CInt(Left(Coordenada, 2))
        Minuto = VBA.CInt(Mid(Coordenada, 4, 2))
        Segundo = VBA.CInt(Mid(Coordenada, 7, 2))
        Centesimo = VBA.CInt(Right(Coordenada, 2))
        
        Grau2Decimal = ((((Centesimo / 100) + Segundo) / 60) + Minuto) / 60 + Grau
        GrauParaDecimal = VBA.CDbl(Grau2Decimal)
        
    ElseIf VBA.TypeName(Parametro) = "Range" Then
        If Parametro.Cells.Count = 1 Then GoTo Texto
        mtzSaida = Parametro.Value
        
        For i = LBound(mtzSaida, 1) To UBound(mtzSaida, 1) Step 1
            For j = LBound(mtzSaida, 2) To UBound(mtzSaida, 2) Step 1
            
                Coordenada = mtzSaida(i, j)
                If Coordenada <> vbNullString Then
                    Grau = VBA.CInt(Left(Coordenada, 2))
                    Minuto = VBA.CInt(Mid(Coordenada, 4, 2))
                    Segundo = VBA.CInt(Mid(Coordenada, 7, 2))
                    Centesimo = VBA.CInt(Right(Coordenada, 2))
                    
                    Grau2Decimal = ((((Centesimo / 100) + Segundo) / 60) + Minuto) / 60 + Grau
                    mtzSaida(i, j) = Grau2Decimal
                Else
                    mtzSaida(i, j) = 0
                End If
            Next j
        Next i

        GrauParaDecimal = mtzSaida
  
    End If
Exit Function
DeuErro:
    Resume Next
End Function

Segue também um modelo onde essa UDF Matricial funciona. Vai encontrá-las nas células azuis.

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 21/03/2016 8:08 pm
(@golfinhu)
Posts: 4
New Member
Topic starter
 

Fernando, era EXATAMENTE isso que eu queria!

Então o dia foi produtivo para nós dois, pois ambos aprendemos algo novo (eu graças a você) [e aos outros que ajudaram também]

Entendi agora como funciona a função prestes a receber uma matriz como parâmetro, algo relativamente simples e que deixa o código muito mais 'profissional'

Realmente seu código ficou muito bom, como disse, à prova de erros, eu dei uma olhada por cima e já entendi bastante coisas, agora vou dar uma olhada mais a fundo para compreender melhor o código!

Meus sinceros muito obrigado, você me ajudou de mais mesmo!

Com certeza esta é uma coisa que poderemos aplicar a códigos futuros!

um grande abraço!

 
Postado : 21/03/2016 9:13 pm
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Bom dia Srs.,

Fiquei um pouco curioso. Não acompanhei o tópico todo, mas existe algum impedimento em fazer por fórmulas?

Segue minha humilde contribuição né... ;)

[EDIT]
Antes de mais nada.... Eu não fiz nada demais, além de utilizar a fórmula que já existia... Existem possíveis erros nela, como por exemplo, um dígito para algum valor.... dá erro... mas foi só uma breve solução...

Depois dessa solução, acho que não precisa de mais ninguém quebrando a cabeça...
kkkkk
[/EDIT]

Qualquer coisa da o grito.
Abraço

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 22/03/2016 6:56 am