web 2.0


Circulando valores duplicados no Excel 2007

Uma ferramenta de validação de dados no Excel extremamente útil e pouquíssima utilizada é a ferramenta de circular dados inválidos.

Esta ferramenta está disponível no Excel 97-2003, por exemplo, mas por ela estar enterrada na barra de ferramentas “auditoria de fórmulas” são poucas as pessoas que a conhecem e as pessoas que conhecem raramente usam porque acabam esquecendo que ela existe.

Com a nova interface(introduzida no Excel 2007), ela foi colocada juntamente com a validação e ficou fácil aplicá-la ao nosso trabalho. Neste exemplo, circularemos valores duplicados, porém esta ferramenta pode ser aplicada a qualquer valor inválido (como se fosse uma formatação condicional). Assim, assumindo que possuímos um conjunto de dados validados para valores únicos, mas no qual há valores repetidos, podemos circular os duplicados como segue:

• Com a área validada, ative a guia Dados e selecione a opção Circular Dados Inválidos:

validação de dados no excel 2007

Figura 1-1 Circulando dados inválidos

Feitos isso, todos os valores duplicados no intervalo que contém a validação de dados serão marcados conforme mostra a figura:

circular dados inválidos no Excel
Figura 1-2 Valores duplicados circulados

Tags: ,

Microsoft Office

Valor por extenso no Excel

Tempos atrás (e põe tempo nisso) me vi as voltar com o desafio de escrever uma função personalizada no Excel que escrevesse números por extenso até a casa dos trilhões de reais. Passados alguns anos, novamente fui solicitado pela mesma função e fui obrigado e desenterrar o meu Excel Addin.

O AddIn é auto-instalável bastando apenas clicar duas vezes sobre ele (baixe o arquivo em Extenso no Excel). Para criar um sistema de auto-instalação de AddIn, você deve proceder como segue:

Option Explicit
Dim ExtensoInstalado    As Boolean

Private Sub Workbook_AddinInstall()
   ExtensoInstalado = True
End Sub

Private Sub Workbook_Open()
    Dim naLista     As Boolean
    Dim nAddIn      As AddIn
    Dim nomeArq     As String

For Each nAddIn In AddIns
    If nAddIn.Name = ThisWorkbook.Name Then
        naLista = True
    End If
Next

If Not ThisWorkbook.IsAddin Then Exit Sub
Application.Workbooks.Add
    If Not ExtensoInstalado Then
        If Not naLista Then
            AddIns.Add (ThisWorkbook.FullName)
            MsgBox "O suplemento 'Extenso' foi instalado com sucesso...", vbInformation, "Suplemento instalado..."
        End If

            For Each nAddIn In AddIns
                If nAddIn.Name = ThisWorkbook.Name Then
                    nomeArq = nAddIn.Title
                End If
            Next
       
        Application.EnableEvents = False
        AddIns(nomeArq).Installed = True
        Application.EnableEvents = True
       
   
    End If
End Sub


O restante da UDF você pode ver no AddIn.

Tags: , , ,

VBA

Excel 2010 Formatação Condicional Barra de Dados

Neste vídeo dou uma rápida prévia sobre a nova formatação condicional utilizando barra de dados no Excel 2010. Como todos já sabem, o Excel 2007 já vem com várias ferramentas de business intelligence e tais ferramentas foram melhoradas no Excel 2010. Neste caso específico, nós saímos de barras de dados simples para barra de dados turbinadas, com muitas novidades para todos os amantes de Excel.



Tags: , , , ,

Microsoft Office

Excel 2010: Novos elementos do copiar e colar

Neste vídeo dou uma rápida prévia sobre o copiar e colar no Office 2010, em especial no Excel 2010. Como todos já sabem, o Office 2010 introduziu o Live Preview que é uma visualização prévia de uma formatação. Pois bem, este live preview foi transferido para o copiar e colar, trazendo grandes ganhos e benefícios para os usuários.

Tags: , , , ,

Microsoft Office

Curso Excel 2003 sobre ADO e ADOX (ActiveX Data Objects) - Parte 5

CURSO ADO e ADOX COMPLETO

 

Caso você ainda não tenha lido a quarta parte, você pode acessá-la em ADO ADOX (ActiveX Data Objects).


2.7.     Tratamento de Erros

Dada a natureza estrita de um banco de dados será impossível ter um código infalível, portanto, é importante que o leitor saiba tratar os erros que possam aparecer para que possíveis problemas sejam resolvidos.

No código anterior possuo um tratamento de erro, embora não o use em todos os exemplos deste curso para não ser pedante com cada código escrito.

Geralmente utilizamos as seguintes instruções para lidar com os erros:

·         On Error GoTo “Rótulo”

·         On Error Resume Next

No primeiro caso, quando o erro ocorre o código é remitido para um rótulo dentro da rotina, por exemplo:

Sub RecordsetLike(ByVal strBusca As String, ByVal Tipo As String)

   

    On Error GoTo Err_Handler

'   Código a ser executado entra aqui

 

    Exit Sub

 

Err_Handler:

    MsgBox Err.Description, vbCritical, Err.Number

    Resume Limpar

End Sub

Note que antes do rótulo há a instrução Exit Sub. Esta instrução se faz necessária para evitar a execução do código logo abaixo do rótulo. Esta parte somente é executada quando há um erro.

O leitor pode ou não definir uma mensagem personalizada, mas se o erro é imprevisível o melhor e deixar em aberto a questão e passar a descrição do erro e o número do erro como é feito no exemplo acima.

Uma outra forma de tratar o erro é utilizar a segunda instrução conforme abaixo:

Sub RecordsetLike(ByVal strBusca As String, ByVal Tipo As String)

   

    On Error GoTo Err_Handler

   

'   Código a ser executado entra aqui

   

Limpar:

    On Error Resume Next

    rs.Close

    Set rs = Nothing

    Exit Sub

 

Err_Handler:

    MsgBox Err.Description, vbCritical, Err.Number

    Err.Clear

    Resume Limpar

End Sub

On Error Resume Next instrui o VBA a continuar a operação em caso de erro. O leitor precisa notar duas coisas aqui:

1.Adição da linha Err.Clear à Adiciono esta linha para limpar o erro causado antes do rótulo Limpar. O motivo para isso é que acima nós resumiremos o código neste ponto após o primeiro erro porém...

2.... Ao resumir no rótulo Limpar caso o primeiro erro tenha sido na abertura do recordset nós não teremos nenhum recordset para fechar o que causaria novo erro (conforme figura abaixo). Então, nós limpamos o erro antes de seguirmos para o rótulo Limpar e ali instruímos o código a continuar em caso de novo erro. Se não fizermos isso, entramos em um loop eterno na primeira instrução On Error GoTo:

Figura 25 Erro retornado ao tentar fechar recordset que ainda não foi aberto

Obviamente que apenas passar a mensagem ao usuário não resolve o seu caso, pois você deseja saber o que está ocorrendo e caso o problema seja no código, você quererá corrigi-lo para evitar recorrência dos problemas.

Como estamos lidando com um banco de dados, talvez a melhor forma de fazermos isso seja através de uma tabela onde “logamos” os erros os quais são futuramente analisados e caso sejam problemas no código os mesmos sejam retificados.



CURSO ADO e ADOX COMPLETO

 

Tags: , , , , ,

Microsoft Office | VBA

Curso Excel 2003 sobre ADO e ADOX (ActiveX Data Objects) - Parte 4

CURSO ADO e ADOX COMPLETO

 

Caso você ainda não tenha lido a terceira parte, voce pode acessá-la em ADO ADOX (ActiveX Data Objects).

2.5  Contando registros em um recordset

Uma propriedade importante de um recordset é a propriedade Recordcount. Diferentemente do DAO (onde precisamos mover dentro dos registros e retornar ao primeiro para não obtermos o famigerado -1), no ADO a contagem é feita diretamente, bastando apenas determinar a propriedade.

O código abaixo dará o número de registros contidos na tabela Categorias (pois selecionamos todos os registros ao utilizarmos o asterisco). Em termos gerais, a propriedade retorna o número de registro no recordset o qual pode ou não representar a tabela por completo:

Sub RecordsetRecCount()

    Dim cn      As New ADODB.Connection

    Dim rs      As New ADODB.Recordset

   

    cn.Open strCn

    rs.Open "SELECT * FROM Categorias", cn, adOpenKeyset, adLockPessimistic

   

    Debug.Print rs.RecordCount

   

    rs.Close

    cn.Close

    Set rs = Nothing

    Set cn = Nothing

 

End Sub

2.6.     Abrindo um recordset baseado em critériosAbrindo um recordset baseado em critérios

Abrir uma tabela por completo em um recordset nós somos, de certo modo, redundantes. Com isso quero dizer que normalmente nós desejamos apenas parte dos dados e não todos. Por exemplo, poderíamos querer todos os clientes iniciados pela letra “C”.

Neste caso, nós precisamos determinar na instrução SQL o que desejamos que seja retornado em nosso recordset. Para isso nós utilizamos a cláusula WHERE.

O ideal nestes casos é termos uma string declarada para escrevermos a instrução SQL. Com a string pronta nós a introduzimos no argumento do método Open e o comprimento da instrução é dastricamente reduzido.

Vejamos alguns exemplos de instruções SQL que fazem isso. Aqui vemos como passar um parâmetro, pois como queremos basear a consulta em uma condição não podemos amarrar a condição dentro da rotina.

Sub executarRs()

    Call RecordsetWhere(1)

End Sub

 

Sub RecordsetWhere(ByVal código As Long)

    Dim cn          As New ADODB.Connection

    Dim rs          As New ADODB.Recordset

    Dim strSQL      As String

   

    strSQL = "SELECT * FROM Produtos WHERE CódigoDaCategoria=" & código

    cn.Open strCn

   

    With rs

        .Open strSQL, cn, adOpenKeyset, adLockPessimistic

        .MoveFirst

        Debug.Print "Registros para o recordset da categoria " _

            & código & " --> " & .RecordCount

        Debug.Print vbCr & "NOMES DOS PRODUTOS"

        Do While Not .EOF

            Debug.Print !NomeDoProduto

            .MoveNext

        Loop

    End With

   

    rs.Close

    cn.Close

    Set rs = Nothing

    Set cn = Nothing

 

End Sub

Uma vez executado, teremos a seguinte impressão na janela imediata;

 

 

 

 

Figura 23 Resultado da impressão do recordset

O exemplo acima assume uma passagem de parâmetro numérica. Suponha um outro cenário onde o que queremos é retornar todos os produtos contendo uma string qualquer, como proceder?

O próximo exemplo será um pouco mais elaborado e utilizaremos o comparador LIKE. Precisaremos de um formulário como segue:

 

Figura 24 Formulário de seleção

No formulário digitaremos o que buscamos e escolheremos o tipo de busca. O botão Executar deve conter a seguinte instrução:

Private Sub cmdExecutar_Click()

    Call RecordsetLike(Me.txtBusca, Me.cboTipo.Value)

End Sub

A rotina RecordsetLike recebe dois argumento: 1) texto de busca e 2) o tipo de busca.

Sub RecordsetLike(ByVal strBusca As String, ByVal Tipo As String)

    Dim cn          As New ADODB.Connection

    Dim rs          As New ADODB.Recordset

    Dim strSQL      As String

    Dim lngLin      As Long

   

    On Error GoTo Err_Handler

   

'   Determina a opcao escolhida pelo usuário para remontar

'   a string de busca

    Select Case UCase(Tipo)

 

'       Se for registros que "terminam em" alguma coisa

'       adicionar o apóstrofo e sinal de percentual

'       para indicar que termina na string digitada pela usuário

        Case "TERMINA EM"

            strBusca = "'%" & strBusca & "'"

           

        Case "COMEÇA EM"

            strBusca = "'" & strBusca & "%'"

           

        Case "CONTÉM"

            strBusca = "'%" & strBusca & "%'"

           

        Case Else

            MsgBox "Opção de busca inválida. Cancelando a operação...", _

                vbExclamation

            Exit Sub

    End Select

   

           

   

    strSQL = "SELECT * FROM Produtos"

    strSQL = strSQL & " WHERE NomeDoProduto Like " & strBusca

    cn.Open strCn

   

    lngLin = 3

    With rs

        .Open strSQL, cn, adOpenKeyset, adLockPessimistic

        .MoveFirst

       ActiveSheet.Cells(1, 1) = "Registros para o recordset da categoria " _

            & strBusca & " --> " & .RecordCount

        ActiveSheet.Cells(2, 1) = "NOMES DOS PRODUTOS"

        Do While Not .EOF

             ActiveSheet.Cells(lngLin, 1) = !NomeDoProduto

             lngLin = lngLin + 1

            .MoveNext

        Loop

    End With

   

Limpar:

    On Error Resume Next

    rs.Close

    cn.Close

    Set rs = Nothing

    Set cn = Nothing

    Exit Sub

 

Err_Handler:

    MsgBox Err.Description, vbCritical, Err.Number

    Resume Limpar

End Sub

Diferentemente do caso numérico, aqui nós precisamos envelopar a string em apóstrofos. Também utilizamos o sinal de percentual para determinar o tipo de busca, isto é se o sinal aparece no início da string a busca é para produtos terminados com aquela string.

Por outro lado, se o sinal aparece no final da string a busca é para produtos iniciados por aquela string. E, finalmente, se a string contiver um sinal no início e fim, então a busca é por produtos que contenham a string.

CURSO ADO e ADOX COMPLETO

Tags: , , , , , ,

Microsoft Office | VBA

Curso Tabela Dinâmicas Excel 2003 em vídeo

Neste vídeo você aprenderá como criar uma tabela dinâmica utilizando VBA. Para iniciar, você aprenderá como criar um nome dinâmico no Excel 2003 para determinar a área a ser utilizada na tabela dinâmica. O curso completo pode ser encontrato em nossa loja em:


Curso Tabela Dinâmica Interativo para Excel 2003.


Outros exemplos:

Tutorial Tabela Dinâmica (Parte 1)
Tutorial Tabela Dinâmica (Parte 2)

 

 

Tags: , ,

Microsoft Office

Curso Excel 2003 sobre ADO e ADOX (ActiveX Data Objects) - Parte 3

Caso você ainda não tenha lido a segunda parte, voce pode acessá-la em ADO ADOX (ActiveX Data Objects).

2.2 Abrindo, fechando e limpando um recordset

Antes de abrir um recordset é necessário a abertura de uma conexão, a menos que você queira utilizar um recordset desconectado (veja mais adiante como proceder).

Recordset está vinculado à base de dados e por este motivo precisamos da conexão aberta antes de proceder, sem isso a abertura de um recordset falhará.

Assim como a conexão, nós utilizamos o método Open para abrir o recordset e o método Close para fechá-lo.

Vejamos então um exemplo simples de como proceder:

Sub exRecordset ()

    Dim cn      As New ADODB.Connection

    Dim rs      As New ADODB.Recordset

    Dim strCn   As String

   

    strCn = "Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;"

    strCn = strCn & "Data Source=C:\Northwind.mdb;"

 

    cn.Open strCn

    rs.Open "SELECT * FROM Categorias", cn, adOpenKeyset, adLockPessimistic

   

    Debug.Print rs.Fields.Count

   

    rs.Close

    cn.Close

    Set rs = Nothing

    Set cn = Nothing

 

End Sub

Quando iniciamos o processo de abertura de um recordset nós precisamos determinar alguns argumentos utilizados pelo método Open conforme mostra a figura abaixo:

Figura 21 Argumentos do métodos Open

·         Source à Refere-se à fonte de dados para o recordset. Para ser mais específico, Source refere-se a uma instrução SQL a qual retornará os registros que desejamos. No exemplo acima, a instrução é de seleção (SELECT) de todos os registro (*) da tabela Categorias. A complexidade da instrução dependerá do tipo recordset que você deseja;

·         ActiveConnection à Refere-se à conexão que utilizaremos para retornar os dados;

·         CursorType à Refere-se ao tipo de cursor utilizado. O cursor determina como podemos movimentar dentro dos registro. Por exemplo, o cursor adOpenForwardOnly somente permite movimento para frente dentro do recordset o que implica que não podemos utilizar o método MovePrevious do recordset para mover para o registro anterior ao atual na ausência de um lock, pois neste contexto não é permitido;

·         LockType à Refere-se ao travamento dos registros para edição. Imagine o cenário onde um usuário acessa um registro agora para edição e outro acessa os mesmos dados dois segundos depois, o que ocorreria? Sem o devido travamento edições feitas por um usuário podem ser sobrescritas por outro. Para evitar isso, travamos os registros. adLockPessimistic pode ser usado para evitar acesso/edição simultânea ao passo que adLockOptimistic permitiria acesso e que um registro seja editado e salvo dependendo de qual usuário chama primeiro a execução do comando.

É basicamente isso que o leitor precisa saber para abrir um recordset. A maior dificuldade é realmente construir a instrução SQL que executará o que desejamos. Veja apêndice para maiores informações.

 

2.3 Abrindo, fechando e limpando um recordset desconectado (disconnected recordset)

No exemplo anterior vimos como abrir um recordset conectado, isto é, ele está conectado à base de dados sem a qual ele não existe. Por outro lado, um recordset desconectado implica que o mesmo não depende de uma conexão para existir.

Recordset desconectado serve uma função similar a uma matriz. Por exemplo, poderíamos ter a seguinte matriz

Matriz(0) = 0

Matriz(1) = 1

Matriz(2) = 3

Enquanto que não há nada de errado em criar uma matriz, até porque nós podemos redimensioná-la e preservar os itens existentes, um recordset desconectado pode nos servir bem para tal cenário, pois podemos adicionar campos a ele e depois apenas adicionamos os dados que desejamos (os quais podem vir de uma fonte conectada).


Vejamos como isso é feito:

Sub exRecordsetDesconectado()

    Dim rs      As New ADODB.Recordset

       

    With rs.Fields

        .Append "ID", adInteger

        .Append "Nome", adVarChar, 55

        .Append "Endereço", adVarChar, 255

        .Refresh

    End With

   

    With rs

        .Open

        .AddNew

            !ID = 100

            !Nome = "Robert Friedrick Martim"

            !Endereço = "Qualquer lugar"

        .Update

    End With

   

    Debug.Print rs.Fields(1).Name

    Debug.Print rs.Fields(1).Value

    rs.Close

    Set rs = Nothing

 

End Sub

O leitor provavelmente está se perguntando para que serve isso. Suponha que você deseja abrir um recordset, porém, como já sabemos, o mesmo estará conectado a base de dados o que nos causa um pequeno problema.

Uma solução seria declarar um recordset na área de declarações globais (no topo de tudo na janela do VBE) e armazenar os dados de um recordset conectado neste recordset global desconectado. Como ele não será destruído enquanto não for explicitamente feito, podemos utilizá-lo para trabalhar os dados sem a necessidade de solicitá-los várias vezes à fonte de dados.

Alternativamente, podemos utilizar o recordset desconectado para simplesmente armazenar uma matriz muito grande a qual não sabemos o limite superior de antemão, mas sabemos o número de colunas o que evitaria redimensionamento desnecessário de matriz (além da necessidade de preservar informações já contidas nela como um Redim Preserve).

 

2.4 Navegação de um recordset

No tópico sobre abertura de um recordset vimos brevemente o tipo de cursor que podemos utilizar nele. Agora, veremos como estes cursores afetam a navegação pelos registros.

Navegar pelo registros é bastante simples e precisamos apenas observar o tipo de cursor que desejamos utilizar e sua combinação com o tipo de lock do banco de dados para evitar erros.

Vejamos um exemplo:

Sub exNavegacao()

    Dim cn      As New ADODB.Connection

    Dim rs      As New ADODB.Recordset

   

    cn.Open strCn

   

    With rs

        .Open "SELECT * FROM Categorias", cn, adOpenKeyset, adLockOptimistic

        .MoveFirst

        Do While Not .EOF

            Debug.Print !NomeDaCategoria

            .MoveNext

        Loop

        Debug.Print vbCr

        .MovePrevious

        Do Until .BOF

            Debug.Print !NomeDaCategoria

            .MovePrevious

        Loop

    End With

       

   

    rs.Close

    cn.Close

    Set rs = Nothing

    Set cn = Nothing

 

End Sub

No exemplo acima listamos as categorias do início ao fim e depois do fim até o início. Os métodos utilizados na navegação são:

·         MoveFirst à Move o cursor para o primeiro registro do recordset;

·         MoveNext à Move o cursor para o próximo registro do recordset dado o registro atual;

·         MovePrevious à Move o cursor para o registro anterior do recordset dado o registro atual;

Poderíamos também utilizar MoveLast o qual teria o efeito oposto do método MoveFirst.

Caso o leitor tente utilizar adOpenForwardOnly sem um lock apropriado um erro ocorrerá conforme já explicado:

 

 


Figura

22 Método MovePrevious inválido na ausência de um lock e cursor adOpenForwardOnly

 

 

 

Tags: , , , ,

Microsoft Office | VBA

Curso Interativo Excel 2003 Tabela Dinâmica

Apresenta aqui um curso rápido e introdutório ao conceitos de tabela dinâmica no Excel. Esta introdução é hospedada no site MS Office Gurus em inglês e deve ser acessado no seguinte link: http://www.msofficegurus.com/uploads/SCFXL03_TD_VID_SAMPLES/T21/T21_training.htm



Esta primeira parte faz parte do curso completo de tabelas dinâmicas disponibilizado em nossa loja: http://loja.msofficegurus.com/como-fazer-excel-2003-treinamento-interativo-tabelas-dinamicas.html

Não deixe de fazer os nossos test drives!

Tags: , ,

Microsoft Office

Curso Excel 2003 sobre ADO e ADOX (ActiveX Data Objects) - Parte 2

Neste tópico veremos alguns dos objetos importantes do ADO tais como “Connection” e “Recordset” assim como propriedades e métodos destes objetos os quais utilizamos para efetuar tarefas em nosso banco de dados. Você pode checar o primeiro artigo sobre ADO ADOX (ActiveX Data Objects).

Inicio pela conexão, pois nós precisamos de uma conexão aberta para abrir conjuntos de registros (recordsets) e efetuar operações em registros e tabelas como inserção, exclusão e edição de registros.

Vejamos então como abrir uma conexão em ADO.

Via de regra, para abrir um conexão ADO nós utilizamos o método Open de um objeto Connection. A parte importante aqui é a string de conexão. Conforme já explicado, podemos obter tal string diretamente do banco de dados através da propriedade Connection do objeto CurrentProject. Feito isso, basta copiar a string para utilização no seu projeto Excel.

Uma outra alternativa é utilizar um Data Link. Data Link será discutido mais adiante no curso.

Se a fonte de dados muda, então uma string é mais apropriada, pois não está ligada a uma fonte específica, bastando apenas adaptar conforme necessário (ou criar uma função para retornar a string dado certos parâmetros). De qualquer modo, a decisão final ficará a cargo mesmo de quem programa.

Para abrir a conexão podemos utilizar o seguinte código:

Sub conexao()

    Dim cn      As ADODB.Connection

    Dim strCn   As String

   

    strCn = "Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;"

    strCn = strCn & "Data Source=C:\Northwind.mdb;"

   

    Set cn = New ADODB.Connection

    cn.Open strCn

End Sub

Note que acima, primeiramente declaramos o objeto, em seguida o instanciamos e finalmente o abrimos utilizando o método Open  do objeto Connection para abrir a conexão. Uma alternativa a isso é simplesmente declarar e instanciar ao meu tempo e logo a seguir abrir a conexão:

Sub conexao()

    Dim cn      As New ADODB.Connection

    Dim strCn   As String

   

    strCn = "Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;"

    strCn = strCn & "Data Source=C:\Northwind.mdb;"

   

    cn.Open strCn

   

End Sub

Uma vez que a conexão esteja aberta e tenhamos terminado o seu uso, nós precisamos fazer duas coisas com ela:

1.Fechá-la

2.Limpá-la da memória

Para fechar uma conexão nós utilizamos o método Close do objeto. Para limpar o objeto da memória nós o setamos como sendo Nothing (nada):

cn.Close

Set cn = Nothing

Portanto, o processo completo entre declaração, abertura, fechamento e limpeza da conexão ficará:

Sub conexao()

    Dim cn      As New ADODB.Connection

   

    cn.Open strCn

   

'   Executaremos algo neste espaço

   

    cn.Close

    Set cn = Nothing

 

End Sub

Agora que o leitor já sabe como efetuar os passos acima, vejamos como abrir um recordset (conjunto de registros) o qual depende de uma conexão aberta para ser viável.

Tags: , , , ,

Microsoft Office | VBA