VBA – Aumente a segurança de seus projetos VBA

 

Logo VBA

Código de autoria do colega Felipe Dasi, colaborador do blog e do nosso fórum.

O conjunto de código abaixo serve para proteger seu arquivo de projeto VBA. Ele faz com que, caso o projeto VBA esteja desprotegido, todo os conteúdo de código dos módulos e planilha sejam excluídos, dificultando o hackeamento de seu aplicativo.

O código abaixo promove a proeza. Os comentários auxiliam na orientações deste e são do próprio autor.

Colocar em Estapasta_de_trabalho:

Option Explicit
 
Private Sub Workbook_Open()
      If Application.Version > 9 Then
            Dim VisualBasicProject As Object
            On Error Resume Next
            Set VisualBasicProject = ActiveWorkbook.VBProject
            If Not Err.Number = 0 Then
 
      End If
      'DESABILITA ESC E INICIA RELOGIO
      Application.EnableCancelKey = xlDisabled
      Run "IniciaRelogio"
      End If
End Sub
 
'
'TODAS AS POSSIBILIDADES
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
      Run "ParaRelogio"
      'PODE COLOCAR CODIGO PROPRIO AQUI
      Run "IniciaRelogio"
End Sub
 
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
      Run "ParaRelogio"
      'PODE COLOCAR CODIGO PROPRIO AQUI
      Run "IniciaRelogio"
End Sub
 
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Excel.Range)
      Run "ParaRelogio"
      'PODE COLOCAR CODIGO PROPRIO AQUI
      Run "IniciaRelogio"
End Sub
 
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
      Run "ParaRelogio"
      'PODE COLOCAR CODIGO PROPRIO AQUI
      Run "IniciaRelogio"
End Sub
 
Private Sub Workbook_BeforeClose(Cancel As Boolean)
      Run "ParaRelogio"
      'PODE COLOCAR CODIGO PROPRIO AQUI'
End Sub

Colocar em um módulo VBA:

'Se a senha em A1 for igual a 123
'Se a senha em Comentários em propriedades da Planilha = 456
'Se a senha do VBA = 123
'RESULTADO O projeto VBA é aberto
'Resumindo, se uma das senha não bater o VBA é apagado
'Se você tirar a senha de A1 e Salvar, a planilha pode ser usada normalmente, mas
' se o usuário quebrar a senha, ao acessar o modulo o VBA serás apagado.
Option Explicit
 
Public IdleTime As Date
 
Private Sub DeletaVBA()
      With ThisWorkbook
            If Plan1.[A1] = "123" _
               And .BuiltinDocumentProperties("Comments") = "456" Then
                  'COLOCANDO A SENHA CORRETA DO VBA E MANTENDO AS OUTRAS DUAS EM A1 E EM PROPRIEDADES O RELOGIO NÃO É ATIVADO.
               'CASO CONTRARIO O RELOGIO É ATIVADO E EM 5 SEGUNDOS O PROJETO VBA SERÁ APAGADO.
                  Run "ParaRelogio"
                  Exit Sub
            Else
                  If .VBProject.Protection = 0 Then   'unlocked
                        Run "ParaRelogio"
 
                        Dim Component As Object
 
                        ' AQUI DELETA TODOS MODULOS DO VBA
                        For Each Component In .VBProject.VBComponents
                              With Component.CodeModule
                                    .DeleteLines 1, .CountOfLines
                              End With
                        Next
 
                        'SALVA AS ALTERAÇÕES FEITAS NA PLANILHA
                        .Save
                        'SE QUISER COLOCAR UMA MENSAGEM
                          MsgBox "SENHA(S) INCORRETA(S) - " & _
                               "TODOS OS MODULOS SERÃO APAGADOS... :o)"
                        Workbooks.Open (.FullName)
                        .Close
                  Else
                        'INICIA A CONTAGEM DO RELOGIO SE VBA FOR QUEBRADO
                        Run "IniciaRelogio"
                  End If
            End If
      End With
      Exit Sub
 
End Sub
 
Private Sub IniciaRelogio()           
      If Plan1.[A1] = "123" _
         And ThisWorkbook.BuiltinDocumentProperties("Comments") = "456" _
         Then Exit Sub
 
            'AQUI É O TEMPO DE ABERTURA DO VBA
      IdleTime = Now + TimeValue("00:00:05")
 
      Application.OnTime IdleTime, "DeletaVBA"
End Sub
 
Private Sub ParaRelogio()
      On Error Resume Next
      Application.OnTime EarliestTime:=IdleTime, _
                         Procedure:="DeletaVBA", Schedule:=False
End Sub

O código e melhorias estão sendo discutidas em nosso fórum:

http://www.tomasvasquez.com.br/forum/viewtopic.php?f=6&t=249&start=10

Bom proveito! Valeu Felipe!

Dicas – Eliminando linhas em branco de um texto

Duvido muito que não tenha passado por isso. Você copia um texto de uma certa origem, normalmente uma página de internet e copia ele no seu editor de texto (tanto faz, Word, ferramenta de desenvolvimento, etc). O resultado é um texto cheio de espaços e linhas em branco no mínimo muito indesejadas.

Em outra oportunidade falarei mais sobre o software notepad++, uma ferramenta de edição de arquivo baseados em texto muito utilizada por desenvolvedores Web e WebDesigners, além de ser um excelente substituto do já ultrapassado Bloco de Notas. Bom, de posse do programa (http://notepad-plus-plus.org/) coloque seu texto em um novo arquivo (o que contém linhas em branco) e selecione a opção TextFX > TextFX Edit > Delete Blank Lines.

Voilá! Seu texto está livre das linhas em branco! Abaixo uma imagem que mostra a opção funcionando:

Bom proveito!

Referências

http://a4apphack.com/index.php/featured/tricks-with-notepad

VBA – Lendo um arquivo texto linha a linha (sem FileSystemObject)


Bom, como falei sobre o mesmo problema outro dia em C#, nada mais justo do que publicar em VBA também, até porque a dúvida surgiu no fórum também.

A rotina abaixo faz o trabalho de abrir e ler uma arquivo no formato texto linha a linha. A idéia é permitir alterar o código de tal forma que se for preciso fazer uma análise do conteúdo da linha, fica fácil de fazer:

Option Explicit
 
Public Sub LeArquivoTexto()
    Dim Arquivo As Integer
    Dim CaminhoArquivo As String
    Dim TextoArquivo As String
    Dim TextoProximaLinha As String
    Dim ContadorLinha As Long
 
    'Configura a leitura do arquivo
    Arquivo = FreeFile
    CaminhoArquivo = "C:\temp\arquivo.txt"
 
    'Abre o arquivo para leitura
    Open CaminhoArquivo For Input As Arquivo
    ContadorLinha = 1
    'Lê o conteúdo do arquivo linha a linha
    Do While Not EOF(Arquivo)
        Line Input #Arquivo, TextoProximaLinha
        TextoProximaLinha = TextoProximaLinha & vbCrLf
        TextoArquivo = TextoArquivo & TextoProximaLinha
    Loop
 
    'Coloca na janela de verificação imediata
    Debug.Print TextoArquivo
 
    'Fecha o arquivo
    Close Arquivo
 
End Sub

Como destacado no título do arquivo, a vantagem deste método, apesar de menos legível, é não precisar carregar a dependência da biblioteca do FileSystemObject, usando somente os recursos padrão do Visual Basic.

Bom proveito!

ASP.NET – Adicionando mensagens do ValidationSummary

Faz tempo que tinha essa necessidade. Já que utilizamos o ValitadionSummary como um concentrador de mensagens de erro, porque não mantê-lo, inclusive para mostrar nossas próprias mensagens, além daquelas que os controles de validação do ASP.NET WebForms nos fornece?

Haviam algumas opções a isso, como criar seus próprios validators, utilizar o CustomValidator em alguns casos ou até um BulletList apontando para o mesmo CssClass no ValitadionSummary para dar a impressão de se tratar da mesma lista. Bom, nenhuma delas era uma solução completa, já que cheiravam a POG.

Bom, uma navegada na internet é o código abaixo me é apresentado:

public class ValidationError : IValidator
{
    private ValidationError(string message)
    {
        ErrorMessage = message;
        IsValid = false;
    }
 
    public string ErrorMessage { get; set; }
 
    public bool IsValid { get; set; }
 
    public void Validate()
    {
        // no action required
    }
 
    public static void Display(string message)
    {
        Page currentPage = HttpContext.Current.Handler as Page;
        currentPage.Validators.Add(new ValidationError(message));
    }
}

Crie esta classe em um local acessível ao seu projeto Web. Agora, no momento em que desejar adicionar uma mensagem, basta usar a seguinte linha de código:

ValidationError.Display("Oops, Aconteceu algum erro.");

Heresia ou não, quase tão simples quando ativar um MessageBox, não? Quando esse código é chamado, o efeito é o mesmo do que tivesse ativado uma função de um CustomValidator (sem client side) e a mensagem aparecerá dentro do ValidationSummary. Mais explicações técincas e créditos no post do autor da proeza:

http://blogs.msdn.com/b/simonince/archive/2008/02/28/adding-messages-to-a-validation-summary.aspx

Bom proveito!