quinta-feira, 14 de abril de 2011

Um lembrete quando utilizar late binding

Cuidado com algumas constantes...
Por exemplo, no Outlook VBA, o formato do texto do e-mail pode ser definido como olFormatHTML desde que a referência à versão corrente do Outlook esteja marcada!
No caso de late binding, lembre-se de que não há referência, portanto, neste exemplo o código retornará um erro.
Basta trocar o "olFormatHTML" por 2 que é a constante correspondente.
Ficaria assim:
email.BodyFormat = 2 (late binding) e
email.Bodyformat = olFormatHTML (early binding).
No Help dos VBA's do Office, pode encontrar todas as constantes necessárias para o dia a dia do programador.

;-)

sábado, 9 de abril de 2011

Compactando via VBA

Onde pretendo aplicar esta solução, o prompt do comando é bloqueado, portanto, o Shell não funciona.
De qualquer forma, fica aqui o código para quem quiser compactar usando o 7Zip ou WinRAR.
Para compactar um por um, basta fazer um loop e vir trocando o nome dos arquivos, idem para as senhas.
;-)

Sub teste()
Dim ret As Long
ret = Shell("C:\Arquivos de programas\WinRAR\rar a -pteste c:\base.rar c:\base.mdb")
End Sub

Sub teste7z()
Dim ret
ret = Shell("C:\Arquivos de programas\7-Zip\7z a -pteste c:\base.7z c:\base.mdb")
End Sub

Protegendo com senha os arquivos compactados pelo Windows





Poderia ser mais intuitivo, mas existe a possibilidade de proteger com senha quando se compacta um arquivo pelo próprio Windows, sem utilizar um compactador de terceiros.
Clique com o botão direito sobre o arquivo a ser compactado, selecione Enviar para > Pasta compactada (zipada).
No arquivo zipado que se criou, clique com o botão direito do mouse e clique em Explorar.
No menu arquivo, aparece então a opção de adicionar senha.

;-)


Compactando com senha todos os arquivos de uma pasta


Estou tentando fazer essa tarefa via VBA, mas enquanto não encontro solução... segue a dica de um compactador que faz esse trabalho, o PeaZip.
Trabalha com vários formatos (*.7Z, *.rar, *.zip e outros), e tem versão "Portable" que funciona a partir do pendrive.
Ainda não testei, mas aparentemente muito bom e simples de usar.
Já ia esquecendo... os arquivos são individuais, ou seja, trata-se de criar um zip para cada cada arquivo e não um zip contendo todos os arquivos!

http://www.peazip.org

;-)

terça-feira, 29 de março de 2011

Mais um código para obter via VBA o IP do seu computador

Com os devidos créditos nos comentários.


Option Explicit

Global num_ip As String

' VBA MODULE: Get all IP Addresses of your machine
' (c) 2005 Wayne Phillips (http://www.everythingaccess.com)
' Written 18/05/2005
'
' REQUIREMENTS: Windows 98 or above, Access 97 and above
'
' Please read the full tutorial here:
' http://www.everythingaccess.com/tutorials.asp?ID=Get-all-IP-Addresses-of-your-machine
'
' Please leave the copyright notices in place.
' Thank you.
'
'Option Compare Database

'A couple of API functions we need in order to query the IP addresses in this machine
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Declare Function GetIpAddrTable Lib "Iphlpapi" (pIPAdrTable As Byte, pdwSize As Long, ByVal Sort As Long) As Long

'The structures returned by the API call GetIpAddrTable...
Type IPINFO
dwAddr As Long ' IP address
dwIndex As Long ' interface index
dwMask As Long ' subnet mask
dwBCastAddr As Long ' broadcast address
dwReasmSize As Long ' assembly size
Reserved1 As Integer
Reserved2 As Integer
End Type

Public Function ConvertIPAddressToString(longAddr As Long) As String

Dim IPBytes(3) As Byte
Dim lngCount As Long

'Converts a long IP Address to a string formatted 255.255.255.255
'Note: Could use inet_ntoa instead

CopyMemory IPBytes(0), longAddr, 4 ' IP Address is stored in four bytes (255.255.255.255)

'Convert the 4 byte values to a formatted string
While lngCount < 4

ConvertIPAddressToString = ConvertIPAddressToString + _
CStr(IPBytes(lngCount)) + _
IIf(lngCount < 3, ".", "")

lngCount = lngCount + 1

Wend

End Function

Public Sub GetIPAddresses(Optional blnFilterLocalhost As Boolean = False)

Dim Ret As Long, Tel As Long
Dim bytBuffer() As Byte
Dim IPTableRow As IPINFO
Dim lngCount As Long
Dim lngBufferRequired As Long
Dim lngStructSize As Long
Dim lngNumIPAddresses As Long
Dim strIPAddress As String

On Error GoTo ErrorHandler:

Call GetIpAddrTable(ByVal 0&, lngBufferRequired, 1)

If lngBufferRequired > 0 Then

ReDim bytBuffer(0 To lngBufferRequired - 1) As Byte

If GetIpAddrTable(bytBuffer(0), lngBufferRequired, 1) = 0 Then

'We've successfully obtained the IP Address details...

'How big is each structure row?...
lngStructSize = LenB(IPTableRow)

'First 4 bytes is a long indicating the number of entries in the table
CopyMemory lngNumIPAddresses, bytBuffer(0), 4

While lngCount < lngNumIPAddresses

'bytBuffer contains the IPINFO structures (after initial 4 byte long)
CopyMemory IPTableRow, _
bytBuffer(4 + (lngCount * lngStructSize)), _
lngStructSize

strIPAddress = ConvertIPAddressToString(IPTableRow.dwAddr)

If Not ((strIPAddress = "127.0.0.1") _
And blnFilterLocalhost) Then

'Replace this with whatever you want to do with the IP Address...
num_ip = strIPAddress

End If

lngCount = lngCount + 1

Wend

End If

End If

Exit Sub

ErrorHandler:
MsgBox "An error has occured in GetIPAddresses():" & vbCrLf & vbCrLf & _
Err.Description & " (" & CStr(Err.Number) & ")"

End Sub

Criando arquivos MDE no Access 2007 - Parte III

Apesar de ter escrito em outros lugares que não ia baixar o hotfix (achei uma falta de respeito com o consumidor não corrigir esse erro banal até o SP2), mudei de idéia e fui buscar o arquivo.
Para minha surpresa, foi necessário cadastrar meu e-mail para receber as instruções!
Bem, feito isso, olha só o que veio no e-mail demonstrando o pouco caso com o problema.

:-(


INFORMAÇÕES IMPORTANTES

Para sua conveniência, colocamos o hotfix solicitado em um site HTTP. Você pode baixar o hotfix desse site e com isso evitamos ocupar a sua caixa de entrada de emails.

AVISO Esse hotfix não foi submetido a um teste completo. Portanto, destina-se somente a sistemas ou computadores enfrentando o mesmo problema descrito em um ou mais artigos da Base de Dados de Conhecimento Microsoft listados no campo "Números do artigo da base de dados" da tabela que se encontra no final desta mensagem de email. Se você não tiver certeza de que algum problema específico de compatibilidade ou instalação esteja associado a esse hotfix, será recomendável aguardar pela próxima versão do service pack. O service pack incluirá uma versão totalmente testada dessa correção. Sabemos que pode ser difícil determinar se algum problema de compatibilidade ou instalação está associado a um hotfix. Assim, se desejar confirmar se o hotfix corrige o seu problema específico, ou se algum problema de compatibilidade ou instalação está a ele associado, os analistas de suporte dos Serviços de Atendimento ao Cliente poderão ajudá-lo. Para obter mais informações sobre como contatar o suporte, copie o link a seguir e cole-o no seu navegador da Web:

http://support.microsoft.com/contactus/

Para obter opções adicionais de suporte, copie o link a seguir e cole-o no seu navegador da Web:

http://support.microsoft.com/

Antes de instalar o hotfix
------------------------------

Se você decidir instalar esse hotfix, observe os itens a seguir:

Não implante um hotfix em um ambiente de produção sem antes testá-lo.

Faça backup do sistema ou computador que receberá o hotfix antes de instalá-lo.

Criando arquivos MDE no Access 2007 - Parte II

Achei muito bom a opção de criar um arquivo MDE em vez do ACCDE no Access 2007, porém encontrei problemas...
Um MDE criado no 2007 simplesmente não abre em outro computador!
Gastando meu precioso tempo numa pesquisa na net, descobri que o problema é de conhecimento da Microsoft e até disponibilizou um hotfix para sanar o inconveniente.
Inadmissível um problema tão tosco e básico, lamentável mesmo.

link para o hotfix:
http://support.microsoft.com/kb/943249

;-)

terça-feira, 22 de março de 2011

Cadê os comandos do Office 2010?

Segue link com o "de -> para" dos comandos do Office 2010 em relação ao 2003.
Não sei quanto tempo o link estará no ar.
É necessário ter o Silverlight instalado.
Estranhamente o tutorial não roda no Chrome.

http://office2010.microsoft.com/en-us/word-help/learn-where-menu-and-toolbar-commands-are-in-office-2010-HA101794130.aspx#_Toc268688374

Se não estiver enganado, acho que já vi algo parecido para o Office 2007...

;-)

Criando arquivos MDE no Access 2007

Estava preocupado em trabalhar com o Access 2007, pois sempre criava MDE's para proteger meus códigos VBA e nesta versão, vi somente a opção de criação de ACCDE's, o equivalente do primeiro caso.
Questionando no fórum ExpertAccess, nosso colega JPaulo indicou um texto interessante que reproduzo parte dele mais abaixo, onde descreve-se a funcionalidade de criar MDE a partir de banco de dados MDB da versão 2003 no Access 2007.
Façam um teste.
Criem um mdb no formato 2003 e na faixa de opções "Ferramentas de banco de dados" aparecerá o botão "criar MDE".
Usando o formato ACCDB, na faixa de opções aparece "Criar ACCDE".
Muito bom, tomara que na versão 2010, o recurso seja mantido.

;-)

Obs.: costumo colocar o link + o texto, pois frequentemente os sites são atualizados e por vezes, o link torna-se inválido. Procuro dessa forma, preservar o texto original para futuras consultas aqui.

link do texto:
http://office.microsoft.com/en-us/access-help/6-key-considerations-when-creating-access-2007-databases-HA010219005.aspx


trecho do texto:
TIP In previous versions of Access this was called a Microsoft Database Executable (MDE) file. The functionality and creation process are the same. If you open an older (Access 2002 or Access 2003) MDB file in Access 2007, a Make MDE command appears in the Database Tools group on the Database Tools tab in place of the Make ACCDE command that appears when you're working in an Access 2007 database.

quinta-feira, 10 de março de 2011

Mais um site sobre Outlook...

... com muitas informações!!!
http://www.outlookcode.com/

;-)

segunda-feira, 7 de março de 2011

Agenda no Office

Tenho visto muita gente desenvolvendo uma agenda no Accesss, mas creio que "reinventar a roda" é perda de tempo.
Segue minha opinião:
A maioria dos computadores (para não dizer todos) que têm o Access instalado, invariavelmente têm o MS Outlook também.
Então para que criar uma agenda no Access, se você tem no MS Outlook uma excelente agenda, totalmente funcional e completa?
Via VBA é possível fazer os dois aplicativos interagirem entre si, obtendo assim a produtividade esperada do pacote Office.
Falar em produtividade aqui no blog já é "chover no molhado", mas insisto no assunto para que os colegas programadores gastem menos tempo com soluções mirabolantes em VBA e entendam que a integração entre os aplicativos Office é o caminho para a produtividade.
Quem já vem acompanhando o blog, sabe que tenho a mesma opinião quanto a criação de controle de estoque em Excel: funciona quando a quantidade de itens é pequena (eu diria que até uns 50 itens no estoque e com pouca movimentação de entradas e saídas).
É o aplicativo inadequado para a tarefa.
Dúvidas? Vejam o famoso Northwind que é o banco de dados exemplo que vem no Office (não sei se na versão 2010 ainda vem).
Onde encontrar muita coisa de programação VBA no Outlook: http://www.rsoutlook.com


;-)

Zipando via VBA com o 7Zip

Segue uma adaptação de um código que eu peguei na internet.
Não é de minha autoria, mas vou deixar aqui para futuras consultas.
É bom ressaltar que o 7Zip é um compactador free e até o último comparativo que fiz, tinha uma taxa de compressão melhor que a do WinRAR.


Option Explicit

Dim nome_zip As Variant
Dim pasta_a_zipar As Variant
Dim strDate As String
Dim Pasta_destino As String
Dim oApp As Object


Sub Zipar_tudo_com_7Zip()

'Pasta onde estará o arquivo zipado
Pasta_destino = "C:\Users\todorok\Desktop\"

'Pasta que contém os arquivos a serem zipados
pasta_a_zipar = "C:\Users\todorok\Desktop\Kaizen\"

'Arquivo zip que contém os arquivos compactados
nome_zip = Pasta_destino & "backup" & ".zip"

'Criar um arquivo zip vazio
Call Novo_zip_vazio(nome_zip)

Set oApp = CreateObject("Shell.Application")
'Copiar os arquivos para dentro do arquivo zip vazio
oApp.NameSpace(nome_zip).CopyHere oApp.NameSpace(pasta_a_zipar).Items

'Aguardar o término da compactação
On Error Resume Next
Do Until oApp.NameSpace(nome_zip).Items.Count = oApp.NameSpace(pasta_a_zipar).Items.Count
Application.Wait (Now + TimeValue("0:00:01"))
Loop
On Error GoTo 0

MsgBox "Fim!"
End Sub

Sub Novo_zip_vazio(sPath)
'Se já existir um arquivo zip, apagá-lo e criar um novo
If Len(Dir(sPath)) > 0 Then Kill sPath
Open sPath For Output As #1
Print #1, Chr$(80) & Chr$(75) & Chr$(5) & Chr$(6) & String(18, 0)
Close #1
End Sub

domingo, 23 de janeiro de 2011

Linguagem de programação dirigida a iniciantes

Chegou o Small Basic, uma linguagem de programação que, segundo a Microsoft, destina-se a crianças ou pessoas que desejam aprender a programar de forma simples e intuitiva.
Ainda não instalei, mas logo farei um teste.
Para pessoas que já têm alguma experiência, em princípio não vejo muita coisa interessante, mas o que me chamou a atenção é que o Small Basic é orientado à objetos e imagino eu que, pela sua simplicidade, deve ajudar a quem vive no mundo da orientação à eventos, aprender os novos conceitos.

Links:
Download do Small Basic:
http://blogs.msdn.com/b/smallbasic/archive/2010/06/11/small-basic-v0-9-is-here.aspx

FAQ:
http://msdn.microsoft.com/en-us/beginner/ff384239.aspx

Manuais:
http://msdn.microsoft.com/en-us/ff423682
Obs.: infelizmente o português BR não estava disponível no momento em que escrevia este post, mas o link para o português PT está ativo.

Home do Small Basic:
http://msdn.microsoft.com/en-us/beginner/ff384126.aspx

;-)

Verificando a versão do Excel via VBA

Esta questão foi postada num dos grupos de discussões que participo.
A resposta é bem simples, basta usar o Application.Version que será mostrada a versão do Excel que está sendo executada.
Abra o VBA (ALT + F11), tecle CTRL + G para abrir a janela de verificação imediata e digite Debug.Print Application.Version

O resultado será:
Versão 8 para o Excel 97
Versão 9 para o Excel 2000
Versão 10 para o Excel 2002
Versão 11 para o Excel 2003
Versão 12 para o Excel 2007
Versão 14 para o Excel 2010

A pergunta mais óbvia: cadê a versão 13?
Se alguém souber, me mande por e-mail, apenas por curiosidade.
Certamente, a necessidade de verificar a versão deve-se a alguma incompatibilidade de comandos entre a versão onde foi desenvolvido e a versão onde será executado o programa.
Nestes casos, minha recomendação também é simples:
Se você sabe que tem mais de uma versão do Excel instalado na sua empresa, desenvolva sempre para a versão mais antiga e use sempre que possível, late binding para evitar problemas com referências aos outros aplicativos do MS Office.
A pequena perda de performance no late binding é praticamente imperceptível, visto que os PC's atuais são bem rápidos e raramente aplicações desenvolvidas no Excel têm a performance como foco principal.


;-)

domingo, 19 de dezembro de 2010

Mais uma opção ao Microsoft Office

Tirando o BrOffice, acho que a falta de sucesso de outras suítes vem justamente de seus maiores objetivos: tentarem se parecer com o Microsoft Office.
Talvez algum desenvolvedor ainda tenha uma super idéia, faça algo realmente diferente e quem sabe, chame mais a atenção dos usuários em geral.

Link para quem quiser experimentar:
http://product.thinkfree.com/office

A propósito, +/- U$ 50.

;-)

quinta-feira, 9 de dezembro de 2010

Uma "outra" opção em suíte Office livre - LIBRE OFFICE

Outra entre aspas porque me parece ser o BrOffice, "largado" pela Sun e continuado pelos fundadores do antigo projeto.
Ainda não testei, fica para outra ocasião e depois eu coloco aqui as impressões.
No time que toca o projeto, um brazuca, Claudio Filho que dentre outras coisas, co-fundou a comunidade BROffice.org.

Link:
http://www.documentfoundation.org/

;-)

segunda-feira, 6 de dezembro de 2010

Conectando o Excel 2007 via ADO


Sub ado_2007()
Dim cnn As New ADODB.Connection

cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\teste_ado.xlsx;" & _
"Extended Properties=" & Chr(34) & "Excel 12.0;HDR=Yes" & Chr(34)

cnn.Open
cnn.Close
End Sub

sábado, 13 de novembro de 2010

Separar planilhas

Esta é uma tarefa que sempre aparece nos grupos de discussão: dividir uma planilha a partir de um campo como critério.
Por exemplo, a partir de planilha de vendas onde estão os dados de todos os vendedores, criar uma nova planilha para cada vendedor.
Muitas soluções criativas já foram propostas e eu vou deixar a minha aqui.
Fiz em Access pela facilidades que o aplicativo oferece.

Baixem o aplicativo no link, na pasta "Exemplos Excel" (apesar de ser em Access...).
O código está aberto para quem quiser melhorar ou personalizar, basta abrir segurando a tecla shift.

http://www.4shared.com/dir/jufLzdx2/Compartilhado.html

;-)

domingo, 7 de novembro de 2010

MariaDB

Um nome incomum e curioso, mas acreditem, é um banco de dados.
Criado pelos desenvolvedores do MySQL que não se deram bem com a Sun Microsystems, parece ser algo promissor, exatamente na contramão do MySQL, que neste momento aparenta estar com o futuro obscuro e incerto.

http://www.maria.org

;-)

quinta-feira, 4 de novembro de 2010

Verificando o tamanho das pastas e listando no Excel


Option Explicit

Dim objFSO As Object

Dim pasta As Object

Dim subpasta As Object

Dim linha As Integer

Dim diretorio As String

Dim UserFile As String

Private Sub cmd_verifica_Click()

UserFile = GetDirectory("Selecione a pasta")

If UserFile = "" Then

Exit Sub

Else

Me.MousePointer = fmMousePointerHourGlass

Call subpastas(UserFile)

Me.MousePointer = fmMousePointerDefault

Unload Me

End If

End Sub

Sub subpastas(diretorio As String)

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set pasta = objFSO.GetFolder(diretorio)

Set subpasta = pasta.SubFolders

ActiveSheet.Range("A1").CurrentRegion.Clear

linha = 2

ActiveSheet.Cells(1, 1) = "Nome da pasta"

ActiveSheet.Cells(1, 2) = "Tamanho"

For Each pasta In subpasta

DoEvents

ActiveSheet.Cells(linha, 1) = Mid(diretorio, 3, 99) & "\" & pasta.Name

ActiveSheet.Cells(linha, 2) = pasta.Size

linha = linha + 1

Next

ActiveSheet.Columns("A:B").AutoFit

ActiveSheet.Range("B:B").NumberFormat = "#,##0"

Call classifica

ActiveSheet.Cells(1, 1).Select

End Sub

Sub classifica()

Columns("A:B").Select

ActiveSheet.Sort.SortFields.Clear

ActiveSheet.Sort.SortFields.Add Key:=Range("B2:B100"), _

SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal

With ActiveSheet.Sort

.SetRange Range("A1:B100")

.Header = xlYes

.MatchCase = False

.Orientation = xlTopToBottom

.SortMethod = xlPinYin

.Apply

End With

End Sub


Pesquisar este blog

Arquivo do blog

Quem sou eu

Minha foto
Administrador de Empresas/Técnico em Processamento de Dados. Microsoft Office User Specialist - Excel Proficient. Pós-graduado em Business Intelligence.