Arquivo da tag: VBA

Cuidado com Userform.Hide!

Vejo muitos exemplos de código em VBA que no uso de UserForms, usam o método Hide fechá-lo.

É bom tomar cuidado com o método Hide. Ele não fecha o Form, apenas esconde como o próprio nome diz.

O Unload definitivamente o tira da memória. Para fazer um teste, crie um form vazio, coloque nele um textbox e dois botões. Num deles coloque o Unload Me e no outro o UserForm.Hide.

Crie uma macro para chamar o Form com Userform.Show. Execute esta macro, coloque algum texto no textbox e clique no botão que executa o Hide. Execute a macro para chamar o Form de novo. Veja que o texto digitado continua lá. Agora faça o mesmo teste, mas agora clicando no botão que executa o Unload Me. Veja que a caixa de texto volta vazia.

O que o Hide faz é somente ocultar o Form. Se essa não for a intenção, é bom tomar cuidado com seu uso.

Abraços

Tomás Vásquez
http://www.tomasvasquez.com.br

Desabilitando o botão fechar de um Userform no VBA

Uma necessidade comum em alguns sistemas VBA é evitar que o usuário feche o form involuntariamente. A forma mais comum é captura o evento Query_Close e alterar o valor do parâmetro Cancel.

Porém algumas vezes é necessário que o botão de fechamento nem apareça para alterar. Para isso, basta colocar o código abaixo em um UserForm VBA. Os eventos Initialize e Query_Close já criados tratam de remover o botão do UserForm.

Private Declare Function FindWindowA Lib "USER32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLongA Lib "USER32" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLongA Lib "USER32" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
 
Private Sub UserForm_Initialize()
    Dim hwnd As Long
    hwnd = FindWindowA(vbNullString, Me.Caption)
    SetWindowLongA hwnd, -16, GetWindowLongA(hwnd, -16) And &HFFF7FFFF
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Dim hwnd As Long
    hwnd = FindWindowA(vbNullString, Me.Caption)
    SetWindowLongA hwnd, -16, GetWindowLongA(hwnd, -16) Or &H80000
End Sub

É bom atentar que desaparecer com o botão não desativa o uso do atalho Alt+F4 que fecha a janela.

Bom proveito!

Obtendo informações de um drive no VBA

Colaboração do camarada Robert Martin (http://br.msofficegurus.com/), postou uma dica muito bacana sobre como obter informações de um drive usando o VBA. A função abaixo por exemplo retorna o número de série de um drive baseado em sua letra de referência:

Function SerialPD(ByVal DriveLetter As String) As String
    Dim oFso As New FileSystemObject
    Dim oDrive As Drive
 
    If oFso.DriveExists(DriveLetter) Then
        Set oDrive = oFso.GetDrive(DriveLetter)
        SerialPD = Left(Hex(oDrive.SerialNumber), 4) & "-" & Right(oDrive.SerialNumber, 4)
    Else
        SerialPD = "Drive especificado nao existe."
    End If
 
    Set oDrive = Nothing
    Set oFso = Nothing
 
End Function

É necessária a referência à biblioteca Microsoft Scripting Runtime. No código, o objeto oDrive representa o Drive, que além da propriedade SerialNumber utilizada no código, possui outras como espaço livre, capacidade e sistema de arquivos. Uma documentação completa da biblioteca pode ser vista no site MSDN:

http://msdn.microsoft.com/en-us/library/bkx696eh%28VS.85%29.aspx

Bom proveito e valeu Robert!

Tomás Vásquez
http://www.tomasvasquez.com.br

Retornando o nome da cor com VBA

Um dos problemas do VBA é sua pobreza de bibliotecas. Tá bom, tem bastante coisa sim, mas comparado ao que vemos em linguagens mais novas como .NET e Java, pelo menos para que já desenvolve nestas linguagens sente muita falta de coisas já consideradas simples como enums para representar valores.

Opiniões a parte, os camaradas da OzGrid.com publicaram um função em VBA que retorna o nome da cor com base em um Range passado por parâmetro. Pelo menos ele suporta a principal paleta de cores do Microsoft Office, neste caso do Excel. A função segue abaixo:

Function CellColor(rCell As Range, Optional ColorName As Boolean)
    Dim strColor As String, iIndexNum As Integer
 
    'Written by Dave Hawley of OzGrid.com
    Select Case rCell.Interior.ColorIndex
    Case 1
        strColor = "Black"
        iIndexNum = 1
    Case 53
        strColor = "Brown"
        iIndexNum = 53
    Case 52
        strColor = "Olive Green"
        iIndexNum = 52
    Case 51
        strColor = "Dark Green"
        iIndexNum = 51
    Case 49
        strColor = "Dark Teal"
        iIndexNum = 49
    Case 11
        strColor = "Dark Blue"
        iIndexNum = 11
    Case 55
        strColor = "Indigo"
        iIndexNum = 55
    Case 56
        strColor = "Gray-80%"
        iIndexNum = 56
    Case 9
        strColor = "Dark Red"
        iIndexNum = 9
    Case 46
        strColor = "Orange"
        iIndexNum = 46
    Case 12
        strColor = "Dark Yellow"
        iIndexNum = 12
    Case 10
        strColor = "Green"
        iIndexNum = 10
    Case 14
        strColor = "Teal"
        iIndexNum = 14
    Case 5
        strColor = "Blue"
        iIndexNum = 5
    Case 47
        strColor = "Blue-Gray"
        iIndexNum = 47
    Case 16
        strColor = "Gray-50%"
        iIndexNum = 16
    Case 3
        strColor = "Red"
        iIndexNum = 3
    Case 45
        strColor = "Light Orange"
        iIndexNum = 45
    Case 43
        strColor = "Lime"
        iIndexNum = 43
    Case 50
        strColor = "Sea Green"
        iIndexNum = 50
    Case 42
        strColor = "Aqua"
        iIndexNum = 42
    Case 41
        strColor = "Light Blue"
        iIndexNum = 41
    Case 13
        strColor = "Violet"
        iIndexNum = 13
    Case 48
        strColor = "Gray-40%"
        iIndexNum = 48
    Case 7
        strColor = "Pink"
        iIndexNum = 7
    Case 44
        strColor = "Gold"
        iIndexNum = 44
    Case 6
        strColor = "Yellow"
        iIndexNum = 6
    Case 4
        strColor = "Bright Green"
        iIndexNum = 4
    Case 8
        strColor = "Turqoise"
        iIndexNum = 8
    Case 33
        strColor = "Sky Blue"
        iIndexNum = 33
    Case 54
        strColor = "Plum"
        iIndexNum = 54
    Case 15
        strColor = "Gray-25%"
        iIndexNum = 15
    Case 38
        strColor = "Rose"
        iIndexNum = 38
    Case 40
        strColor = "Tan"
        iIndexNum = 40
    Case 36
        strColor = "Light Yellow"
        iIndexNum = 36
    Case 35
        strColor = "Light Green"
        iIndexNum = 35
    Case 34
        strColor = "Light Turqoise"
        iIndexNum = 34
    Case 37
        strColor = "Pale Blue"
        iIndexNum = 37
    Case 39
        strColor = "Lavendar"
        iIndexNum = 39
    Case 2
        strColor = "White"
        iIndexNum = 2
    Case Else
        strColor = "Custom color or no fill"
    End Select
 
    If ColorName = True Or _
       strColor = "Custom color or no fill" Then
        CellColor = strColor
    Else
        CellColor = iIndexNum
    End If
 
End Function

O uso da função é simples, bastando colocar em alguma célula a seguinte fórmula:

=CellColor(A1,TRUE)

Isso retorna o nome da cor segundo a paleta de cores. Omitir ou mecionar FALSE no segundo parâmetro, por exemplo:

=CellColor(A1,FALSE) OR CellColor(A1)

Trará o código da cor.

Abraços e bom proveito!

Tomás Vásquez
http://www.tomasvasquez.com.br

Fonte: ozgrid.com