Notifications
Clear all

Verificar a existencia de um codigo dentro do vba

17 Posts
2 Usuários
0 Reactions
2,160 Visualizações
(@mprudencio)
Posts: 0
New Member
Topic starter
 

É possivel no VBA o excel executar uma rotina caso uma outra rotina não exista

Exemplo

macro 1()

rotina

end sub

macro 2()

rotina

end sub

macro 3
if macro 1 then

call macro 2

end if

end sub

Ou seja se a macro 1 nao existir em nenhuma parte da planilha vai rodar macro 2 se nao faz nada

A ideia é colocar um codigo de segurança na planilha em esta pasta de trabalho se ele for apagado rode outra rotina pre determinada em dentro de outro codigo.

Isso da pra fazer, alguem ja fez algo assim?

 
Postado : 03/10/2015 5:37 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Uma das possibilidades seria esta:
Verifica seo o Modulo especificado existe e se macro tambem :
Para funcionar tem de habilitar em Referencias a opção "Microsoft Visual Basic For Applications Extensibility"
Fonte : http://www.mrexcel.com/forum/excel-ques ... xists.html

Se pesquisar no Google por : "Checking for the existence of a Macro excel vba" encontrara varios tópicos referente ao assunto.

'=================================================================================
'- CHECK IF A MODULE & SUBROUTINE EXISTS
'- VBA constant : vbext_pk_Proc = All procedures other than property procedures.
'- An error is generated if the Module or Sub() does not exist - so we trap them.
'---------------------------------------------------------------------------------
'- VB Editor : Tools/References - add reference TO ......
'-    .... "Microsoft Visual Basic For Applications Extensibility"
'----------------------------------------------------------------------------------
'- Brian Baulsom October 2007
'==================================================================================
Sub MacroExists()
    Dim MyModule As Object
    Dim MyModuleName As String
    Dim MySub As String
    Dim MyLine As Long
    '---------------------------------------------------------------------------
    '- test data
    MyModuleName = "TestModule"
    MySub = "TesteRotina"
    '----------------------------------------------------------------------------
    On Error Resume Next
    '- MODULE
    Set MyModule = ActiveWorkbook.VBProject.vbComponents(MyModuleName).CodeModule
    If Err.Number <> 0 Then
        MsgBox ("Module : " & MyModuleName & vbCr & "does not exist.")
        Exit Sub
    End If
    '-----------------------------------------------------------------------------
    '- SUBROUTINE
    '- find first line of subroutine (or error)
    MyLine = MyModule.ProcStartLine(MySub, vbext_pk_Proc)
    If Err.Number <> 0 Then
        MsgBox ("Module exists      : " & MyModuleName & vbCr _
               & "Sub " & MySub & "( )  : does not exist.")
    Else
        MsgBox ("Module : " & MyModuleName & vbCr _
            & "Subroutine   : " & MySub & vbCr _
            & "Line Number : " & MyLine)
    End If
End Sub

[]s

 
Postado : 03/10/2015 6:45 pm
(@mprudencio)
Posts: 0
New Member
Topic starter
 

Mauro obrigado pela dica mas meu ingles é praticamente 0, ele nao passa muito de good morning e the book on the table, então nem pensei em pesquisar em ingles, pesquisei em portugues e nao encontrei nada.

Agora falando do codigo não consegui identificar onde deveria alterar o codigo para ele funcionar, se puder ajudar ficaria agradecido.

Por exemplo onde diz MySub = "Number2" o texto number2 é a posição da macro no modulo ou o nome da macro isso ainda esta meio confuso.

 
Postado : 04/10/2015 7:18 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Marcelo, esta macro verifica se Módulo indicado existe e se a "Sub" ou Macro existe:

MySub = "Number2" o texto Number2 é o nome da Macro que pretende verificar se existe, e,
MyModuleName = "TestModule", o texto TestModule é o nome do Módulo, ou seja se o modulo que tem a macro tem este nome e a pessoa alterar o nome a rotina irá dizer que o modulo não existe, isto tambem ajuda no tipo de implementação que quer fazer.

Exemplificando, se em seu modelo você tem a Macro de nome "Private Sub MinhaRotina()" que está no "Módulo1", então definimos nas variaveis :
'- test data
MyModuleName = "Módulo1" - nome do módulo
MySub = "MinhaRotina" - nome da macro

Achei bem interessante sua ideia, logico que toda a eficacia d que pretendemos construir com vba no excel depende do usuário habilitar as macros, mas toda tentativa é valida.

Quanto ao ingles, você pode estar utilizando google translation, ajuda bastante, só tem de tomar cuidado que as vezes é traduzido algumas instruções que tem de estar em ingles.
De uma olhada no link abaixo, tem praticamente tudo sobre VBA projects, modulos, ou procedimentos(macros, Sub), use o tradutor pelo menos para saber a que se refrem as macros indicadas, você tem desde verficar se o projeto está bloqueado até listar na planilha o nome e tipo dos componentes no arquivo.
Programming The VBA Editor
http://www.cpearson.com/excel/vbe.aspx

[]s

 
Postado : 04/10/2015 5:13 pm
(@mprudencio)
Posts: 0
New Member
Topic starter
 

Mauro mais uma vez obrigado, sou um iniciante em VBA e um grande critico no quesito segurança, infelizmente a Microsoft não da muita importância para isso, afinal os meios de se quebrar senha do projeto são simples demais.

Ate o presente não encontrei nada que fosse no minimo satisfatório quando se fala em segurança.

E a ideia no momento é mais didática do que necessária então venho testando varias opções e essa foi uma das que me surgiram a outra foi a do tópico que diz respeito a verificar se existe senha no VBA, que esta neste link.

viewtopic.php?f=10&t=17529

Entao por uma questão de tentativa se conseguir fazer as duas coisas funcionarem juntos talvez isso torne o codigo vba mais seguro.

Vamos ver no que vai dar.

 
Postado : 04/10/2015 5:33 pm
(@mprudencio)
Posts: 0
New Member
Topic starter
 

Mauro inseri o codigo em um modulo a habilitei a referencia que vc indicou fechei o arquivo e abrir novamente habilitando macros, depurei o codigo e nao funcionou como esperado, ele nao reconheceu nem o codigo nem o modulo.

Criei um novo modulo dei o nome TestModule e dentro desse modulo criei uma rotina com o nome sub Number2

Ve se fiz algo de errado por favor.

 
Postado : 04/10/2015 5:54 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Ainda não entendi o que exatamente voce deseja Marcelo, mas a rotina no seu modelo está OK.
Ao executar o trecho

    '- MODULE
    Set MyModule = ActiveWorkbook.VBProject.vbComponents(MyModuleName).CodeModule
    If Err.Number <> 0 Then
        MsgBox ("Module : " & MyModuleName & vbCr & "does not exist.")
        Exit Sub
    End If

Se não localizar o modulo e/ou Rotina mostra a mensagem,
como em seu teste há o modulo {MyModuleName = "TestModule"} e a rotina {"MySub = "Number2"}, não tem mensagem --> Ok como programado.
No trecho:

'- SUBROUTINE
    '- find first line of subroutine (or error)
    MyLine = MyModule.ProcStartLine(MySub, vbext_pk_Proc)
    If Err.Number <> 0 Then
        MsgBox ("Module exists      : " & MyModuleName & vbCr _
               & "Sub " & MySub & "( )  : does not exist.")
    Else
        MsgBox ("Module : " & MyModuleName & vbCr _
            & "Subroutine   : " & MySub & vbCr _
            & "Line Number : " & MyLine)
    End If

Se encontrar o modulo e não encontra a rotina, emite mensagem.
Encontrando os dois emite a mensagem em que linha do modulo a rotina foi encontrada; em seu exemplço linha de numero 6 --> Ok conforme programado

Obs.: o segundo trecho do código somente irá executar se o primeiro "não executar" , ou seja não gerar erro de "leitura"

 
Postado : 05/10/2015 7:12 am
(@mprudencio)
Posts: 0
New Member
Topic starter
 

Reinaldo se vc depurar o codigo ela deveria trazer como resposta que o modulo e o codigo existem o que na verdade nao acontece.

Pelo menos no que eu entendi a condiçao if para a planilha é verdadeira o que nao acontece.

Ao depurar ele ta indo do if condição

para else

resposta.

E na verdade como coloquei um modulo com o nome indicado ele deveria rodar a rotina dentro do if

 
Postado : 05/10/2015 12:41 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Não o codigo es´ta configurado para trazer mensagem apenas se o modulo e codigo não forem localizados.
Se deseja saber se foi localizado também acrescente um else
algo assim:

    '- MODULE
Set MyModule = ActiveWorkbook.VBProject.vbComponents(MyModuleName).CodeModule
 If Err.Number <> 0 Then
        MsgBox ("Module : " & MyModuleName & vbCr & "does not exist.")
        Exit Sub
else
      msgbox " oK - Modulo existe"
End If
 
Postado : 05/10/2015 12:54 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Veja no seu exemplo com alterações

 
Postado : 05/10/2015 1:04 pm
(@mprudencio)
Posts: 0
New Member
Topic starter
 

Reinaldo obrigado mais uma vez pela intenção de ajudar mas nao funcionou, se eu remover o moduloteste o codigo da erro de compilação sub ou função nao definida.

 
Postado : 05/10/2015 4:46 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Reinaldo obrigado mais uma vez pela intenção de ajudar mas nao funcionou, se eu remover o moduloteste o codigo da erro de compilação sub ou função nao definida.

Marcelo, o código original funciona perfeitamente, tanto no exemplo que postou como no que o Reinaldo adaptou, agora o erro que diz acima acontece porque apos a verificação se o modulo existe é feito a chamada para a macro "N_Existe" que se encontrava no Modulo que você deletou e por isto temos o erro, pois foi deletado o Modulo e a macro.
Para contornar isto, você tem de depois de verificar que o Modulo não existe utilizar um GoTo para verificar se a macro existe, mas tem de ter em mente tambem que este código somente verifica se a macro existe no Módulo mencionado e não em outro, ou seja se deletar o modulo e a rotina for copiado para outro, não terá a confirmação positiva.
Ficaria mais ou menos assim:

ub MacroExists2()
    Dim MyModule As Object
    Dim MyModuleName As String
    Dim MySub As String
    Dim MyLine As Long
    '---------------------------------------------------------------------------
    '- test data
    MyModuleName = "TestModule"
    MySub = "N_Existe"
    '----------------------------------------------------------------------------
    On Error Resume Next
    '-Verifica se o MODULO Existe
    Set MyModule = ActiveWorkbook.VBProject.vbComponents(MyModuleName).CodeModule
    If Err.Number <> 0 Then
        MsgBox ("Module : " & MyModuleName & vbCr & "Não Existe.")
        'Se não Existir irá verificar se a macro existe
        GoTo verificaMacro
        'Exit Sub
    End If
    '-----------------------------------------------------------------------------
    '- SUBROUTINE
    '- find first line of subroutine (or error)
verificaMacro: 'Verifica se a macro existe no modulo
    MyLine = MyModule.ProcStartLine(MySub, vbext_pk_Proc)
    If Err.Number <> 0 Then
        MsgBox ("Sub " & MySub & "( )  : does not exist.")
    Else
        MsgBox ("Module : " & MyModuleName & vbCr _
            & "Subroutine   : " & MySub & vbCr _
            & "Line Number : " & MyLine)
    End If
End Sub

Minha sugestão é que defina primeiro todas as condições que quer verificar para depois ir montando os If e Else nesta rotina, e o ideal é ver atentamente o link que indiquei que tem varias outras rotinas que fazem outros tipos de verificações e tem uma que até lista na aba todos os modulos e componentes.

[]s

 
Postado : 05/10/2015 6:55 pm
(@mprudencio)
Posts: 0
New Member
Topic starter
 

Mauro obrigado de novo, vou testar de novo o codigo que vc postou, mas parece que vc nao entendeu minha pretenção.

Vou tentar ser mais claro.

Imagine que ao desenvolver uma planilha onde vc permita que o usuario utilize ela por 30 dias entao em esta pasta de trabalho ou em um modulo vc coloca um codigo para que o excel verifique se a data atual é igual a data limite, e se for esse arquivo não abra.

Entao imaginando que esse usuario tenha acesso ao projeto vba e exclua esse codigo que vc usa para determinar a data limite de uso do arquivo, o que vai acontecer é que esse arquivo passa a ser liberado para uso.

O que eu pretendo verificar atraves do vba é o fato de essa rotina/modulo existe ou seja se o usuario nao mexer no meu codigo de segurança a planilha vai travar na data correta e pronto, se o usuario alterar/apagar a rotina de segurança para a data o excel vai rodar outra rotina que vai ser a segurança da rotina inicial.

O que o Reinaldo fez foi chamar a rotina que esta no modulo test.

Agora resumindo meu teste

eu tenho 2 codigos

segurança 01

segurança 02

se o usuario apagar/modificar o codigo segurança 01 executa o codigo segurança 02 entao o fato de eu apagar ou nao o codigo/modulo NAO deve interferir no funcionamento da planilham na verdade ele deve travar o uso da planilha caso isso aconteça.

Os codigos eu ja tenho pronto mas eu preciso fazer essa verificação.

 
Postado : 05/10/2015 7:32 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Bom a pergunta era sobre "saber" se um determinado módulo e ou rotina estão presentes no projeto VBA.
O código disponibilizado pelo colega Mauro faz isso e muito bem por sinal.
Como aplica-lo/utiliza-lo depende do programador, dei um exemplo tosco de como pode ser utilizado para acessar uma rotina ou outra, se não atende , pena.
Mas quanto a segurança; se tiver um usuário que sabe abrir seu vba, excluir/inibir o código de "travamento", certamente irá saber/localizar essa verificação e exclui-la tambem.
Em tempo, se o usuário ao invés de excluir a rotina somente "comentar" as linhas, então na procura será localizado a rotina, porem a mesma continuará sem efeito.

 
Postado : 06/10/2015 7:23 am
(@mprudencio)
Posts: 0
New Member
Topic starter
 

Reinaldo so para constar, saber se existe não significa executar. Não é a mesma coisa mas obrigado pela sua ajuda ela sempre sera vista com bons olhos.

E concordo com suas colocações, na verdade eu sou dentre as pessoas que conheço o maior critico de que a segurança em excel é um lixo, porem ate hoje nunca vi ninguém tentar algo semelhante ao que estou tentando, então não sei ate onde é ou nao possivel, pretendo continuar.

Obrigado de novo.

 
Postado : 06/10/2015 8:03 am
Página 1 / 2