Muitas empresas possuem seus processos de negócio apoiados em arquivos do Microsoft Office. Não é raro esbarramos com sistemas inteiros que form desenvolvidos em Access ou Excel por funcionários que sabiam um pouco de VBA .
O problema é quando esses funcionários saem da empresa, o conhecimento de VBA fica restrito a eles. E, se o sistema for muito complexo, pode ser que ninguém mais saiba como ele funciona. Além disso, em algum momento a operação do processo de negócio não escala, devido a limitações dos próprios arquivos, como usuários tentando acessá-los de forma simultânea.
Extrator de fórmulas
Uma das formas de fazer engenharia reversa nessas planilhas é extrair suas macros e fórmulas. O código a seguir foi adaptado a partir de um Gist do Steve Jansen.
Public Sub ExportaCodigoVBA()
'constabtes que identificam o tipo de componente VBA
Const Module = 1
Const ClassModule = 2
Const Form = 3
Const Document = 100
Const Padding = 24
Dim VBComponent As Object
Dim count As Integer
Dim caminho As String
Dim pasta As String
Dim extensao As String
Dim fso As New FileSystemObject
pasta = ActiveWorkbook.path & "\vba"
count = 0
'se o diretório não existe, criamos
If Not fso.FolderExists(pasta) Then
Call fso.CreateFolder(pasta)
End If
Set fso = Nothing
'para cada tipo de componente VBA, definimos a respectiva extensão do arquivo
For Each VBComponent In ActiveWorkbook.VBProject.VBComponents
Select Case VBComponent.Type
Case ClassModule, Document
extensao = ".cls"
Case Form
extensao = ".frm"
Case Module
extensao = ".bas"
Case Else
extensao = ".txt"
End Select
On Error Resume Next
Err.clear
caminho = pasta & "\" & VBComponent.Name & extensao
Call VBComponent.Export(caminho)
If Err.Number <> 0 Then
Call MsgBox("Falha ao exportar " & VBComponent.Name & " to " & caminho, vbCritical)
Else
count = count + 1
Debug.Print "Exported " & Left$(VBComponent.Name & ":" & Space(Padding), Padding) & caminho
End If
On Error GoTo 0
Next
Application.StatusBar = "Exportado com sucesso " & CStr(count) & " arquivos VBA para " & pasta
Application.OnTime Now + TimeSerial(0, 0, 10), "ClearStatusBar"
End Sub