100 Dicas

download 100 Dicas

of 25

Transcript of 100 Dicas

100 Dicas - Parte 1Dica 1 - Abrindo automaticamente um controle ComboboxPara fazer com que o controle Combobox abra automaticamente, basta usar a propriedadeDropdownno evento"Ao receber o foco".Private sub NomeDaCombo_GotoFocus() Me!NomeDaCombo.dropdownEnd subDica 2 - Inibindo mensagens do AccessAo executar uma consulta de ao (DELETE, INSERT ou UPDATE) com o comandoDocmd.RunSQL, uma mensagem do Access exibida informando a quantidade de registros afetadas pela consulta. Veja a imagem:

Para desativar esta mensagem usamos o comandodocmd.SetWarningsDocmd.SetWarnings false 'Desativa a mensagem do Access Docmd.RunSQL "DELETE * FROM tblClientes;"Docmd.SetWarnings true 'Ativa a mensagem do AccessMinha preferncia utilizar o comandoCurrentdb.Executeque no retorna a mensagem do Access e assim economizo duas linhas na digitao.'No retorna mensagem do Access ao executar a consultaCurrentdb.Execute "DELETE * FROM tblClientes;"Pode tambm inibir esta mensagem, configurando o seu Access pelas "Opes" do Access. Vejaaquineste meu artigo.Dica 3 - Abrindo formulrio de cadastro na posio novo registroNa chamada do formulrio basta utilizar o valoracFormAdddo argumentoDataMode'Abre o formulrio direto na posio novo registroDocmd.OpenForm "NomeDoFormulrio",,,,acFormAddUma outra forma passar a propriedade "Entrada de dados" do formulrio paraSIM

Esta tcnica acelera a abertura do formulrio, pois o Access deixa de carregar os registros existentes, contribuindo em muito para o desempenho do seu aplicativo, principalmente se estiver trabalhando em rede.Dica 4 - Contando as linhas de uma ListBoxNa propriedadeFonte do Controledo campo que ir receber a contagem, coloque:=[NomeDoCampoListBox].ListCountDica 5 - Alterando as primeiras letras dos nomes para MaisculasPara corrigir as letras iniciais dos nomes podemos utilizar a funosrtConv()strConv("avelino sampaio",vbProperCase) :::> Avelino SampaioSe deseja atualizar todos os registros de um campo especfico, utilize uma consulta Atualizao com a seguinte configurao:'Ateno: Realize um backup antes de aplicar a consultaCurrentdb.Execute "UPDATE NomeTabela SET NomeCampo = strConv(NomeCampo,3);"

'vbProperCase no reconhecido pelo VBA quando colocado entre as aspas; por'isso foi utilizado o seu valor numrico correspondente(3). Dica 6 - Reconhecendo valores de senhas Case Sensitive.J teve a necessidade de implementar senhas, diferenciando caracteres maisculos de minsculos ? Para esta finalidade utilizamos a funostrComp().strComp("avelino","Avelino",vbBinaryCompare) :::> 1'A funo retorna 0(zero) para strings iguais e 1 para strings diferentes.Veja como pode ser aplicado numa condicionalIF....strSenhaUsuario = Dlooukup("senha","tblUsurios",idUsuario =" & me!idUsuario)If strComp(me!CampoSenha,strSenhaUsuario,vbBinaryCompare) = 1 then msgbox "Senha incorreta....",vbInformation ,"Aviso" ...end if...Dica 7 - Conhecendo a funo eval() para analisar expresses.Gosto muito desta funo que facilita bastante a programao em vrias situaes. A funo retornaTrue(-1) ouFalse(0) conforme a anlise da expresso. Exemplo bem simples:eval("1=2") :::>Retorna false(0)eval("1=1") :::>Retorna true(-1)Vamos supor que voc queira que um determinado boto de seu formulrio seja ativado apenas nos horrios entre s 9 horas e 11 horas da manh:me!NomeBoto.Enabled = eval("time() Between #9:00 am# And #11:00 am#") Agora, vamos supor que voc queira esconder umCampo_B,caso oCampo_Atenha sido preenchido com um dos seguintes valores: Azul, Preto ou Prata.me!Campo_B.visible = eval("""" & me!Campo_A & """ IN('Azul','Preto','Prata')")Dica 8 - Fazendo Download de uma pgina Web para um arquivo local no formato txt.O objetoXMLHTTP usado para baixar a pgina. E a instruoOPENdo Access para criar e gravar em arquivo txt. Leia com ateno os comentrios:Public Sub fncDownloadPagina(Url As String, DestFileName As String)Dim HttpReq As ObjectDim hFile As IntegerOn Error GoTo trataErroSet HttpReq = CreateObject("Msxml2.ServerXMLHTTP.6.0")'--------------------------'Abre a pgina Web indicada'---------------------------HttpReq.Open "GET", Url, False'--------------------------------------'Passa a pgina para a varivel HttpReq'--------------------------------------HttpReq.sendhFile = FreeFile'---------------------------------------------------------------'Cria o arquivo txt no local indicado pela varivel DestFileName'---------------------------------------------------------------Open DestFileName For Output As #hFile'-------------------------------------------------------------------------'Passa o cdigo Html/Xml, que est na varivel HttpReq, para o arquivo txt'-------------------------------------------------------------------------Print #hFile, StrConv(HttpReq.ResponseBody, vbUnicode)'-------------------'Fecha o arquivo txt'-------------------Close #hFileMsgBox "Pgina salva com sucesso...", vbInformation, "Aviso"Sair: Exit SubtrataErro: MsgBox "No foi possvel gravar a pgina. Verifique se o endereo da _ pgina est correto...", vbInformation, "aviso" Resume Sair:End SubMais detalhes sobre o objeto XMLHTTPaquiExemplo de chamada:fncDownloadPagina "http://www.usandoaccess.com.br","c:\SuaPasta\PaginaUA.txt"Dica 9 - Mantendo o foco depois de usar o mtodo Requery, em um formulrio contnuo.Ao usar o mtodo Requery para atualizar a base de dados de um formulrio contnuo, o ponteiro deslocado para o primeiro registro e isto muitas das vezes no o desejado. Ento, para manter o foco no registro atual, aps o uso do Requery, pode ser utilizado o seguinte cdigo:Dim rsrs = Me.BookmarkMe.RequeryMe.Bookmark = rsDica 10 - Usando a instruo NAME do Access para renomear arquivos. raramente utilizada, mas no custa nada voc saber que existe. Uma vez precisei renomear todos os arquivoJPGde uma pasta, acrescentando o ano 2013. Veja o procedimento utilizado e atente para os comentrios:Public Sub fncRenomearJpg(strCaminho as string, Ano as Integer)Dim strArquivo As StringDim strMod as String'---------------------------------------------------'Carrega todos os arquivo jpg na varivel strArquivo'----------------------------------------------------strArquivo = Dir$(strCaminho & "*.jpg")'-------------------------------------------------------------------'Percorre a lista de arquivos jpg, armazenada na varivel strArquivo'--------------------------------------------------------------------Do While Len(strArquivo) > 0 '--------------------------------------------- 'Acrescenta ao nome do arquivo o ANO informado '--------------------------------------------- strMod = strCaminho & Replace(strArquivo, ".", "_" & Ano & ".") '--------------------------------------------------------- 'Renomeia o arquivo utilizando a instruo NAME do Access '--------------------------------------------------------- Name strCaminho & strArquivo As strMod '-------------------------------------- 'Passa para o arquivo seguinte da lista '-------------------------------------- strArquivo = Dir$()LoopMsgBox "Arquivos renomeados com sucesso!", vbInformation, "Aviso"End SubChamando pelo procedimento:fncRenomearJpg "c:\inter\Imagens\",2013Sucesso!

100 Dicas - parte 2Dica 11 - Ativar/desativar por cdigo, as teclas Num Lock, Caps Lock e Scroll Lock.Com a APIGetKeyState() possvel identificar o status de cada uma das teclas Num Lock, Caps Lock e Scroll Lock. Para isso, basta informar o cdigo correspondente ao da tecla na API e obter como resultado o valor 0 ou 1. O valor 0 indica que a tecla est desativada (Led apagado) e o valor 1 que a tecla est ativada (Led aceso).Valores das teclas:Num Lock = 144ou pode fazer ser uso da constantevbKeyNumlock.Caps Lock = 20ou pode fazer ser uso daconstantevbKeyCapital.Scroll Lock = 145Option Compare Database#If VBA7 Then 'verses 2010 e 2013 Public Declare PtrSafe Function GetKeyState Lib "user32"(ByVal nVirtKey As Long) As Long#Else 'verses 2007 e anteriores Public Declare Function GetKeyState Lib "user32"(ByVal nVirtKey As Long) As Long#End if--------------------------------------------------------------------------------------Public Sub fncAtivarDesativarTecla(Tecla&, Ativar As Boolean)Dim ws As ObjectDim T$Set ws = CreateObject("WScript.shell")T = switch(Tecla=144,"{numlock}",Tecla=20,"{capslock}",Tecla= 145,"{scrolllock}")If Ativar Then 'Ativar tecla que se encontra desativada If GetKeyState(Tecla) = 0 Then ws.SendKeys TElse 'Desativar tecla que se encontra ativada If GetKeyState(Tecla) = 1 Then ws.SendKeys TEnd IfSet ws = NothingEnd SubPara ativar a tecla Caps Lock:Call fncAtivarDesativarTecla (20, true)Para desativar a tecla Scroll Lock:Call fncAtivarDesativarTecla (145, false)Dica 12 - Como fazer o cdigo VBA esperar por uma informao do usurio.Em alguns casos necessrio interromper a execuo de um cdigo para aguardar por uma informao do usurio. Nestes casos,utiliza-sedo argumento WindowMode setado paraacDialog, do comando Docmd.OpenForm. No exemplo abaixo, o cdigo aguarda pelo fechamento do formulrio frmRegistro para ento processar as linhas seguintes. Observe os comentrios:Public Sub fncCapturaRegistro()On Error Resume Next'-----------------------------------------------------------------------------'Abre o formulrio frmRegistro, solicitando a interrupo do cdigo (acDialog)'----------------------------------------------------------------------------DoCmd.OpenForm "frmRegistro", , , , , acDialog, 1'---------------------------------------------------------------------------'A rotina prossegue a partir deste ponto, somente quando o usurio fechar 'o formulrio.'A varivel global booRegistrado tem seu valor definido no formulrio 'frmRegistro, por isso necessrio que a rotina aguarde por este valor.'---------------------------------------------------------------------------If booRegistrado = False Then 'Sai do aplicativo DoCmd.Quit acQuitSaveAllEnd IfEnd SubDica 13 - Como atrasar a execuo de um cdigoPara atrasar a execuo de um cdigo usamosdaAPISleep().Option Compare Database#If VBA7 Then 'verses 2010 e 2013 Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)#Else 'verses 2007 e anteriores Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)#End IfAtrasando o cdigo por 3 segundos:Call sleep(3*1000)Veja um exemplo prticoAQUIno meu artigo sobre BINGO.Dica 14 - Disparar eventos de um formulrio A atravs de um formulrio B possvel disparar qualquer evento de um formulrio estando com o foco em outro formulrio. Para isso necessrio trocar o escopoPRIVATEdo evento que se deseja disparar para o escopoPUBLIC. Como exemplo, veja o cdigoabaixode um boto chamado btExcluir do formulrio A.Public Sub btExcluir_Click()On Error Resume NextDoCmd.RunCommand acCmdDeleteRecordEnd SubPara chamar o evento acima pelo Formulrio B, basta utilizar o seguinte comando:forms("NomeFormulrioA").btExcluir_ClickDica 15 - Esconder o AccessCom a combinao de algumas APIs possvel definir o grau de transparncia do Access e/ou seus objetos.O grau de transparncia tem um range que vai de 0 a 255. O valor zero(0) torna o aplicativo totalmente oculto e 255 totalmente visvel.No cdigo abaixo utilizei apenas os valores 0 e 255, mas nada impede que seja feita uma pequena alterao eoutros valores sejam testados.Nota:As APIs sofreram alteraes na sua escrita a partir da verso 2010 do Access. Veja todos os detalhes desta mudananeste meu artigo. Adaptei o cdigo abaixo para atender as diversas verses.Option Compare Database

#If VBA7 Then'-------------------------------------------' verses 2010 e 2013 - 32 e 64 bits'--------------------------------------------Declare PtrSafe Function SetLayeredWindowAttributes Lib "user32" _(ByVal hwnd As LongPtr,ByVal crKey As Long,ByVal bAlpha As Byte,ByVal dwFlags As Long) As Long

Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _(ByVal hwnd As LongPtr, ByVal nIndex As Long) As Long

Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _(ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

#Else'-------------------'verso 2007'------------------Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _(ByVal hwnd As Long, ByVal nIndex As Long) As Long

Declare Function SetLayeredWindowAttributes Lib "user32" _(ByVal hwnd As Long,ByVal crKey As Long,ByVal bAlpha As Byte,ByVal dwFlags As Long) As Long

#End If

'ConstantesPrivate Const GWL_EXSTYLE = (-20)Private Const WS_EX_LAYERED = &H80000Private Const LWA_ALPHA = &H2------------------------------------------------------------------------------------------------Private Function fncOcultarAccess(Ocultar As Boolean) As BooleanDim lngHwnd As LongDim bytNivel As BytelngHwnd = Application.hWndAccessAppbytNivel = IIf(Ocultar, 0, 255)SetWindowLong lngHwnd, GWL_EXSTYLE, GetWindowLong(lngHwnd, GWL_EXSTYLE) Or WS_EX_LAYEREDSetLayeredWindowAttributes lngHwnd, 0, bytNivel, LWA_ALPHAfncOcultarAccess = TrueEnd FunctionEsconder o Access:Call fncOcultarAccess(True)Retornar a visualizar o Access:Call fncOcultarAccess(false)Dica 16 - Como realizar busca de contedo aqui no site UsandoAccessO site possui um excelente sistema de busca utilizando o Google. Est presente nas pginas Tutoriais e Dicas. Faa um teste entrando com palavras ou frases do seu interesse no campo de pesquisa e clique no boto"Pesquisar o site". Exemplo de palavras para pesquisar: somar, contar, ribbons, horas extras, ...

Dica 17 - Trabalhar com vrios tipos de dados na consulta INSERTTenho certeza que voc j teve algum grau de dificuldade para fazer funcionar corretamente uma consulta de ao INSERT.Geralmente,a razo principal desta dificuldade est associada aos tipos de dados (string, data, nmeros, ...) envolvidos no processo.Tenho uma regra para voc: utilizeapstrofeouaspas duplas,independentemente do tipo de dado. Observe com ateno, no cdigo abaixo, os diversos tipos de dados:Private Sub btInsert_Click()Dim strSql$

strSql = "INSERT INTO tblTeste (NomeCliente,DataNascimento,Operadora,"strSql = strSql & "ValorCobrado,Nota,Renovar,Desconto,Pontuao) VALUES "strSql = strSql & "(""Pontocom Informtica""," 'Tipo StringstrSql = strSql & "'15/05/2005'," 'Tipo datastrSql = strSql & "'Vivo'," 'Tipo StringstrSql = strSql & "'50,00'," 'Tipo DuplostrSql = strSql & "'1267'," ' Tipo LongostrSql = strSql & "'-1'," 'Tipo BooleanostrSql = strSql & "'6,50'," 'Tipo MoedastrSql = strSql & "'4'" 'Tipo BytestrSql = strSql & ");"

CurrentDb.Execute strSql

End SubPara o campo NomeCliente utilizeiaspas duplaspelo fato de poder surgir nomes no cadastro com apstrofe. Exemplo: Alexandre D'avilaSegue o arquivo exemplo para voc praticar:ConsultaInsert.zipVeja como fica o cdigo utilizando campos de um formulrio:Private Sub btInsert_Click()Dim strSql$

strSql = "INSERT INTO tblTeste (NomeCliente,DataNascimento,Operadora,"strSql = strSql & "ValorCobrado,Nota,Renovar,Desconto,Pontuao) VALUES "strSql = strSql & "('" & me!NomeCliente & "','" 'Tipo StringstrSql = strSql & me!DataNascimento & "','" 'Tipo datastrSql = strSql & me!operadora & "','" 'Tipo StringstrSql = strSql & me!ValorCobrado & "','" 'Tipo DuplostrSql = strSql & me!Nota & "','" ' Tipo LOngstrSql = strSql & me!Renovar & "','" 'Tipo BooleanstrSql = strSql & me!Desconto & "','" 'Tipo CurrencystrSql = strSql & me!Pontuao & "'" 'Tipo BytestrSql = strSql & ");"

CurrentDb.Execute strSql

End SubNota:para os campos do tipo Mltiplos Valores e Anexo, a tcnica utilizada estneste meu artigo.Dica 18 - Ultrapassando a limitao do operador MOD (resto da diviso)O operador MOD funciona at o numero 2.147.483.647Resultados:2147483647 MOD 97 ::::> 652147483648 MOD 97 ::::> Erro de execuo 6 (ESTOURO)Para substituir o operador MOD possvel utilizar esta frmula::Dividendo - INT(Dividendo/divisor)*DivisorExemplo:2147483648 - Int(2147483648/97)*97 ::::> 66Dica 19 - Tipos de variveis representadas por smbolosGanhar tempo na digitao sempre benvindo e um dos artifcios que voc tem que conhecer a utilizao de smbolos para definir os tipos de variveis. Veja a tabela abaixo:TipoSmbolo

Integer%

Long&

String$

Currency@

Single!

Double#

ByteNenhum

VarianteNenhum

BooleanNenhum

DateNenhum

Exemplo de criao de variveis de diversos tipos:Dim intPedido as integerDim lngPopulacao as longDim strNome as stringDim curValorUnitario as CurrencyDim sglQuantidade as SingleDim dblPi as DoubleQue podem ser digitadas desta forma:Dim intPedido%Dim lngPopulacao&Dim strNome$Dim curValorUnitario@Dim sglQuantidade!Dim dblPi#Ou assimDim intPedido%, lngPopulacao&, strNome$, curValorUnitario@, sglQuantidade!, dblPi# Observe as variveis declaradas abaixo:Dim A, B, C, D, E as IntegerSomente a varivelEque do tipo Integer, o restante do tipo Variante. Para que todas as variveis acima sejam declaradas como as do tipo Integer, necessrio que sejam escritas da seguinte forma:Dim A as Integer, B as Integer, C as Integer, D as Integer, E as IntegerOu utilizar o smbolo correspondente do IntegerDim A%, B%, C%, D%, E%Dica 20 - Usando os dois pontos (:) para representar uma nova linha no VBAPara o VBA, o uso de dois pontos (:) significa que est passando para a prxima instruo. Exemplo de um trecho de cdigo sem o uso de dois pontos.Select Case strcar case "A" to "Z" strTipo = "Maiscula" case "a" to "z" strTipo = "Minscula" case "0" to "9" strTipo = "Nmero" case else strTipo = "Caracter desconhecido"end selectFor k = 1 to 100 j = j + kNextEnto, possvel compactar a escrita desta forma:Select Case strCar case "A" to "Z" : strTipo = "Maiscula" case "a" to "z" : strTipo = "Minscula" case "0" to "9" : strTipo = "Nmero" case else : strTipo = "Caracter desconhecido"end selectFor = k = 1 to 100 : j= j+ k : nextBom estudo!

100 Dicas - parte 3Dica 21 - Registros afetados por Consultas de AoPara obter o nmero de registros afetados porConsultas de Ao,utiliza-se a propriedadeRecordsAffecteddo mtodoCurrentDb. No entanto, para que funcione, preciso passar o mtodoCurrentDbpara uma varivel. Veja como fica o cdigo:Dim bd As DAO.Database'Passando o mtodo para a varivel bdSet bd = CurrentDb'Executando a consulta de Exclusobd.execute "DELETE * FROM tblOS WHERE year(DataAbertura) < year(date)-7"'Informando a quantidade de registros excludosMsgBox "Foram excludos " & bd.RecordsAffected & " registros...", _ vbInformation, "Aviso"Dica 22 - Interceptar cancelamento do InputBoxCom a funo StrPtr() possvel interceptar se a caixa de entradaInputBoxfoi cancelada ou fechada pelo usurio.

Nos dois casos, a funo StrPtr() retorna o valor zero(0) :Dim x as Variantx = InputBox("Clique em cancelar ou fechar", "Testando Cancelar")If StrPtr(x) = 0 Then MsgBox "Voc cancelou!"Else 'Trabalhe aqui o valor informado.End IfAgora, se desejar tambm, detectar se o usurio clicou no boto OK sem ter entrado com a informao na caixa de texto, basta verificar se a varivel x, que do tipo Variant, continua com o seu valor padro Empty (vazio).Dim x as Variantx = InputBox("Clique em cancelar ou fechar", "Testando Cancelar")If x = empty Then MsgBox "Voc cancelou ou clicou no boto OK sem entrar com o valor...!"Else 'Trabalhe aqui o valor x informado.End IfDica 23 - Modificar estrutura de tabelas do back-and atravs do front-endCom as instruesCREATE TABLE,ALTER TABLE,CREATE INDEXeDROP possvel criar, deletar e modificar tabelas. Por exemplo: para adicionar um campo de nomePrecoUnitariodo tipoCurrencyem uma tabela de nometblEstoque, utiliza-se a seguinte instruo:CurrentDb.Execute "Alter Table tblEstoque Add Column PrecoUnitario CURRENCY;"Esta instruo funcionabem para as tabelas locais, porm para as vinculadas preciso indicar na instruoasua real localizao. Agora, imagine que o back-end esteja localizado na pastac:\MinhaPasta\meuBd_be.accdb.Para este caso, a instruo deve ter a seguinte estrutura:Dim strCaminhoBe As StringstrCaminhoBe = "c:\MinhaPasta\meuBd_be.accdb"CurrentDb.Execute "Alter Table [" & strCaminhoBe & "].tblEstoque Add Column PrecoUnitario CURRENCY;"Se o back-end possuir senha de acesso, a instruo esta:Dim strCaminhoBe As StringstrCaminhoBe = "c:\MinhaPasta\meuBd_be.accdb;pwd=MinhaSenha"CurrentDb.Execute "Alter Table [" & strCaminhoBe & "].tblEstoque Add Column PrecoUnitario CURRENCY;"Nota: A tabela no pode estar sendo utilizada no momento da alterao, pois receber mensagem de erro.O aplicativo Telemax possui uma rotina bem interessante que adiciona tabelas inteiras ao back-end, alm de acrescentar novos campos e criar relacionamentos. um aprendizado muito til se voc tiver a necessidade de atualizar o back-end pelo front-end, sem precisar ir ao local.Clique aquipara ter acesso ao Telemax.Dica 24 - Vincular e executar consulta de front-end desvinculadoTem a mesma estrutura apresentada da Dica 23, observe:Dim strCaminhoBe As StringstrCaminhoBe = "c:\MinhaPasta\meuBd_be.accdb;pwd=MinhaSenha"CurrentDb.Execute "DELETE * FROM [" & strCaminhoBe & "].tblEstoque WHERE Descontinuado = -1;"Veja uma variao na estrutura quando utiliza-se o operador IN:Dim strCaminhoBe As StringstrCaminhoBe = "IN '' [;DATABASE=c:\MinhaPasta\meuBd_be.accdb;pwd=MinhaSenha] "CurrentDb.Execute "DELETE * FROM tblEstoque " & strCaminhoBe & " WHERE Descontinuado = -1;"Dica 25 - Chave de segurana em funes pblicasFunes com escopoPublicdevem receber sua especial ateno, pois podem oferecer uma brecha na segurana, mesmo no caso do aplicativo estar na extenso ACCDE.Se o invasor estiver acesso ao Painel de Navegao e chegar at a Janela Imediata do VBA possvel que tente executar tais funes, com a inteno de extrair algo.Por exemplo: vamos supor que voc tenha a funo abaixo no seu aplicativo para descriptografar senha ou outros tipos de informaes sigilosas.Public Function fncDCrip(varChave) As VariantDim i%, k%, strBuff$, strpwd$On Error GoTo trataErrostrpwd = "MNBVCXZLKJ039RTY4U6W"For i = 1 To Len(varChave) k = Asc(Mid$(varChave, i, 1)) k = k - Asc(Mid$(strpwd, i, 1)) strBuff = strBuff & Chr$(k)Next ifncDCrip = strBuffsair: Exit FunctiontrataErro: fncDCrip = 0: Resume sairEnd FunctionDa forma como se encontra a funo acima, qualquer programador com um pouco de experincia poder utilizar a funo, que voc deixou com livre acesso, para decifrar os dados criptografados que voc tenha armazenado em uma tabela.fncDcrip("") :::::> avelinoSoluo: Crie uma chave numrica que impea o funcionamento da funo, caso esta no seja informada corretamente. Veja a alterao da funo:Public Function fncDCrip(varChave, Optional lngChave as long =0) As VariantDim i%, k%, strBuff$, strpwd$On Error GoTo trataErro'------------------------------------------------------'Se no informar a correta chave de segurana, a funo 'passar ao valor 0(zero)'------------------------------------------------------if lngChave 131520 then fncDCrip = 0 Exit Functionend ifstrpwd = "MNBVCXZLKJ039RTY4U6W"For i = 1 To Len(varChave) k = Asc(Mid$(varChave, i, 1)) k = k - Asc(Mid$(strpwd, i, 1)) strBuff = strBuff & Chr$(k)Next ifncDCrip = strBuffsair: Exit FunctiontrataErro: fncDCrip = 0: Resume sairEnd FunctionO programador ao executar a funo sem a chave ou com a chave incorreta receber como resultado o valor 0.fncDcrip("") :::::> 0fncDcrip("",131520) :::::> avelinoQuer ir a fundo sobre tcnicas de segurana para o seu aplicativo? Adquira minha vdeo-aula oferecida no item 3. Cliqueaqui.Dica 26 - Valor padro de varivelAs variveis assumem um valor padro correspondente quando as criamos. Veja o quadro:Tipo VarivelValor padro

Numrica0 (zero)

String"" (comprimento zero)

BooleanFalse

Date00:00:00

VariantEmpty (vazia)

ObjectNothing

Agora, observe bem o procedimento:Public Sub fncValorPadraoVariavel()Dim strA As StringDim intA As IntegerDim blnA As BooleanDim dtaA As DateDim varA As VariantDim objA As ObjectDim strLista$

strLista = "strA = " & IIf(strA = "", """""", strA) & vbNewLinestrLista = strLista & "intA = " & intA & vbNewLinestrLista = strLista & "blnA = " & blnA & vbNewLinestrLista = strLista & "dtaA = " & dtaA & vbNewLinestrLista = strLista & "varA = " & IIf(IsEmpty(varA), "Empty(vazio)", varA) & vbNewLinestrLista = strLista & "objA = " & IIf(objA Is Nothing, "Nothing", objA) & vbNewLine

MsgBox strLista, vbInformation, "Valor padro de varivel...."End SubExecutando o procedimento acima possvel comprovar o valor padro de cada varivel.

Dica 27 - Permitir fechar o Access apenas por botes especficosPara impedir o fechamento do Access pelo boto fechar (canto superior direito), pela combinao de teclas ALT+F4 ou pela Ribbon necessrio que um formulrio de controle se mantenha aberto (podendo ficar oculto).Veja o cdigo utilizado no evento "Ao descarregar" deste formulrio de controle, que impede a sada do Access sem a devida autorizao.Private Sub Form_Unload(Cancel As Integer)If blnSair = False Then MsgBox "Para sair do Access clique no boto [Sair] do formulrio...", _ vbInformation, "Aviso" Cancel = TrueElse 'Sair do Access DoCmd.QuitEnd IfEnd SubObserve que o evento possui o argumentoCancelque permite cancelar o fechamento do formulrio e como conseqncia impede o fechamento do Access.A varivelblnSaircom escopoPublicdeve ser criada em um mdulo global.Public blnSair as booleanComo voc aprendeu na dica 26 acima, a varivel do tipo boolean tem o valor padroFalse. Para ento ser possvel o fechamento do formulrio e conseqentemente o fechamento do Access necessrio passar a varivelblnSairparaTrue.Observe o cdigo abaixo do botobtSairdo formulrio principal, utilizado no exemplo abaixo:Private Sub btSair_Click()blnSair = TrueDoCmd.Close acForm, "frmControleSaida"End SubSegue um pequeno exemplo para voc testar.NaoSair.zipAo rodar o aplicativo exemplo, os formulrios frmPrincipal e frmControlesaida sero carregados, sendo que o formulrio frmControleSaida estar oculto.Nota: Para impedir o carregamento dos formulrios, mantenha a tecla SHIFT pressionada na inicializao.Dica 28 - Como abrir um determinado arquivo atravs do AccessCom o mtodoFollowHyperlink, o aplicativo de origem aberto para o carregamento do arquivo solicitado. Veja abaixo:'O aplicativo Word ser aberto para carregar o arquivo Docxapplication.FollowHyperlink "c:\SuaPasta\SeuArquivo.docx"'O Adobe Reader ser aberto para carregar o arquivo PDFapplication.FollowHyperlink "c:\SuaPasta\SeuArquivo.pdf"'O Windows Media Player ser aberto para carregar o arquivo wmpapplication.FollowHyperlink "c:\SuaPasta\SeuArquivo.wmp"'O navegador padro ser aberto para carregar o siteapplication.FollowHyperlink "http://www.usandoaccess.com.br"Nota:No chame o site sem oHttp:// ,pois o Access exibir uma mensagem de segurana, conforme voc pode observar na imagem abaixo:

No carregamento do site com oFollowHyperlinko navegador no abre maximizado. Se houver a necessidade de abrir o navegador maximizado, possvel utilizar como alternativa o comandoRUNdo Scripting. Veja a funo abaixo:Public Sub fncAbrirSite(strSite As String)Dim ws As Object, xSet ws = CreateObject("WScript.Shell")x = ws.Run(strSite, vbMaximizedFocus, False)Set wShell = NothingEnd SubPara carregar o site, basta chamar pela funocall fncAbrirSite("http://www.usandoaccess.com.br")Dica 29 - Como abrir uma pasta atravs do AccessCom a API SHELL possvel abrir uma pasta ou executar um arquivo. Basta copiar a API abaixo para um mdulo global do seu projeto:Option Explicit'--------------------------------------------------------------------------------------'Copie o cdigo abaixo para um mdulo global do seu projeto'-------------------------------------------------------------------------------------#If VBA7 Then'verses 2010 e 2013Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As LongPtr, _ ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, _ ByVal nShowCmd As Long) As LongPtr#Else'verses 2003 e 2007Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, _ ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, _ ByVal nShowCmd As Long) As Long#End If'--------------------------------------------------------------------------------Exemplo de um boto abrindo uma pasta de nomefotos,localizada no mesmo diretrio do aplicativo:Private Sub btExemplos_Click() Call ShellExecute(0&, "open", CurrentProject.Path & "\fotos", "", "", 1)End SubA API sendo utilizada para abrir uma pgina Web:Dim strSite$strSite ="http://www.usandoaccess.com.br"Call ShellExecute(0&, "",strSite, "", "", 3)Abrindo o teclado virtual do Windows:Call ShellExecute 0, vbNullString, "osk.exe", vbNullString, "C:\", 1Dica 30 - Manipulando pastas e arquivos com a classe FileSystemObserve na imagem abaixo, a classe FileSystem e seus Membros. Lista obtida atravs do Pesquisador de Objetos do VBA.

Veja alguns exemplos de uso desta classe pelo Access:Excluir um arquivoFileSystem.Kill"c:\temp\SeuArquivo.pdf"

Criar uma pastaFileSystem.MkDir"c:\temp"

Excluir uma pastaFileSystem.RmDir"c:\temp"

Nota: A pasta no pode ter arquivos. Use primeiro okillpara excluir os arquivos

Ocultar uma pastaFileSystem.SetAttr"c:\temp", vbHidden

Ocultar um arquivoFileSystem.SetAttr"c:\temp\SeuArquivo.docx", vbHidden

Identificar se a pasta est ocultaFileSystem.GetAttr("c:\temp") = vbHidden

Tamanho do arquivoFileSystem.FileLen("c:\temp\SeuArquivo.accdb") :::> 1056768

Retornar a Data e a Hora da criao ou da ltima modificaoFileSystem.FileDateTime("c:\temp\seuBd.accdb") :::> 20/04/2014 11:00:19

Copiar um arquivoFileSystem.FileCopy"c:\temp\foto.gif", "d:\imagens\foto_bkp.gif"

Nota 1: Arquivo no pode estar em uso.

Nota 2: Observe que podemos copiar alterando o nome do arquivo

Saiba como explorar o HELP do VBA atravsdestaminha vdeo-aula.

Bom estudo!

100 Dicas - parte 4Dica 31 - Nmeros Hexadecimais, Octais e BinriosO VBA disponibiliza as funesHex()eOct()para transformar um nmero Decimal em Hexadecimal e em Octal, respectivamente.hex(302010) :::> 49BBAOct(302010) :::> 1115672No caso depassar o valor de Hexadecimal ou Octal para Decimal, utiliza-se uma das funes de converso Val(), Clng, Cint(), ... com os prefixos&he&oClng("&h"& "49BBA") :::> 302010Clng("&o"& 1115672) :::> 302010Para passar de Decimal para Binrio, utiliza-se a frmula clssica que a de ir agrupandoo restodas sucessivas divises por 2. Exemplo: vamos achar o binrio do valor decimal 35:35 / 2 :::> resto1 Resultado 1717 / 2 :::> resto1 Resultado 88 / 2 :::> resto0Resultado 44 / 2 :::> resto0 Resultado 22 / 2 :::> resto0 Resultado 11 / 2 :::> resto1 Resultado 0Juntando em seqncia, os valores obtidos do resto, obtm-se como resultado, o valor binrio correspondente.35 :::> 100011Observe a funo que realiza o clculo e retorna com o valor Binrio:Public Function fncDecBin(dec)Dim bin$If dec = 0 Then bin = "0"Do While Not dec = 0 bin = (dec - Int(dec / 2) * 2) & bin dec = Int(dec / 2)LoopfncDecBin = binEnd FunctionDe Binrio para Decimal, utiliza-se a frmula que usa o valor de cada posio binria. Exemplo:252423222120:::> 32-16-8-4-2-1(32*1) +(16*0) +(8*0) +(4*0) +(2*1) +(1*1) = 35Observe a funo que realiza o clculo e retorna com o valor Decimal:Public Function fncBinDec(bin)Dim kDim decFor k = Len(bin) To 1 Step -1 dec = dec + ((2 ^ (k - 1)) * Mid(bin, ((Len(bin) + 1) - k), 1))NextfncBinDec = decEnd FunctionVeja agora, o uso da funes acima nestes casos.Para passar de Hexadecimal para Binrio:fncDecBin(Clng("&h"& "49BBA")) :::> 1001001101110111010Para passar de Octal para Binrio:fncDecBin(Clng("&o"& 1115672)) :::> 1001001101110111010Para passar de Binrio para Hexadecimal:Hex(fncBinDec("1001001101110111010")) :::> 49BBADica 32 - Criptografia com resultado binrioAproveitando o que voc aprendeu na dica acima, quero mostrar uma utilidade prtica que a criao de um cdigo de criptografia de nvel 3. Observe bem a funo:Public Function fncCripBin(Senha, Optional Chave As Long = 0) As StringDim cv As Byte, compIf Chave 153045 Then 'Gerando um falso resultado, caso a chave de segurana esteja incorreta. fncCripBin = "101010101010110101010" Exit FunctionEnd IfIf Len(Senha) > 7 Then MsgBox "Comprimento mximo de 7 dgitos...", vbInformation, "Aviso" Exit FunctionEnd IfRandomizecv = Int((Rnd() * 126)) + 1comp = String(7 - Len(fncDecBin(CLng(cv))), "0")fncCripBin = fncDecBin(Oct(senha * cv)) & comp & fncDecBin(cv)End FunctionObserve que temos trs criptografias embutidas na funo para gerar a criptografia final. por isso que aqui chamo de criptografia de nvel 3. A primeira criptografia gerar um valorOCTALda multiplicao da senha informada (valor decimal) pela chave randmica (cv). A chave randmica (cv) varia de 1 a 127:Oct(Senha * cv)Vamos supor que a senha informada seja 102030 e que o valor da chave seja 81. Como resultado da primeira criptografia teremos:Oct(102030*81) :::> 37415356A segunda criptografia a gerao do valor Binrio do resultado Octal.fncDecBin(37415356) :::> 10001110101110100110111100A chave randmica (cv) incorporada ao cdigo Binrio final para que possamos descriptografar a senha. Esta seria a terceira criptografia utilizada.fncDecBin(81) =1010001Como resultado final da criptografia, teremos:fncCripBin(102030, 153045) ::::> 100011101011101001101111001010001Observe que cada vez que rodarmos a funo, com a mesma senha, podemos obter at 127 resultados diferentes de cdigo Binrio. Exemplo:fncCripBin(102030, 153045) :::> 110111110010011010101000010011fncCripBin(102030, 153045) :::> 110110101101011100011001101111010O bom nisso que dificulta, ao extremo, qualquer tentativa de engenharia reversa.Segue abaixo a funo para descriptografar o cdigo Binrio gerado.Public Function fncDCripBin(strBin As String, Optional Chave As Long = 0)Dim cvIf Chave 153045 Then 'Gerando um falso resultado, caso a chave de segurana esteja incorreta: fncDCripBin = "908070" Exit FunctionEnd Ifcv = fncBinDec(Right(strBin, 7))fncDCripBin = CLng("&o" & fncBinDec(Mid(strBin, 1, Len(strBin) - 7))) / cvEnd FunctionAplicando a funo temos como resultado:fncDCripBin("110110101101011100011001101111010", 153045) :::> 102030Nota 1:A razo do argumentoCHAVEutilizado nas funes pblicas, voc encontra clicandoAQUIneste meu artigo - dica 25.Nota 2:Observe que as funes fncDecBin() e fncBinDec() esto presentes na dica 31 acima.Dica 33 - Cuidado com o que voc coloca nas constantes e variveis pblicasSe voc passou o projeto para ACCDE e colocou senha de acesso no VBA e acha que seu cdigo est totalmente seguro; sinto em dizer que voc pode estar cometendo uma falha de segurana. E uma das falhas que costumo observar o programador usar valores sigilosos, principalmente o uso de senha, emconstantesou emvariveispblicas. Exemplo:Option Compare DatabasePublic Const SenhaBe = 102030Como afirmei, aconstanteSenhaBe acima pode ser lida facilmente pela Janela de Verificao Imediata, mesmo estando o VBA protegido por senha. Para sua proteo, utilize a criptografia em valores sigilosos, armazenados nasconstantes.Por exemplo, o valor da senha 102030 sendo armazenado no formato Binrio, usando a funo da dica 32 acima:Option Compare DatabasePublic Const SenhaBe = "110110101101011100011001101111010"Basta utilizar a funo de descriptografia para recuperar o valor da constanteSenhaBE. Observe a parte em vermelho:Dim strCaminhoBe As StringstrCaminhoBe = "c:\MinhaPasta\meuBd_be.accdb;pwd=" & fncDCripBin(SenhaBe, 153045)CurrentDb.Execute "Alter Table [" & strCaminhoBe & "].tblEstoque Add Column PrecoUnitario CURRENCY;"Nota 1: Se a senha for do tipo string, voc pode utilizar as funesda dica 25.Nota 2: Se quiser ir a fundo sobre segurana em cdigo, cliqueaquie adquira a vdeo-aula do item 3.Dica 34 - Convertendo valor de cor, no formato HTML(Hexadecimal) para DecimalAt a verso 2003 era utilizado o valor Decimal nas propriedade de um objeto para identificar a cor, porm a partir da verso 2007 passou a ser utilizado o valor HTML (Hexadecimal). Observe na imagem abaixo, o valor selecionado de uma cor (#FCE6D4) para configurar o fundo de um campo.

Se necessitar utilizar a cor(#FCE6D4) pelo VBA, ter que passar para o formato Decimal. Exemplo de como podemos transformar este valor no formato HTML (Hexadecimal) para Decimal:Cint("&h"& "FC") :::> 252Cint("&h"& "E6") :::> 230Cint("&h"& "D4") :::> 212Pegamos os valores decimais, obtidos de cada parte e passamos para a funo RGB().RGB(252,230,212) :::> 13952764 (valor decimal da cor #FCE6D4)Para configurar a cor de fundo de um campo, pelo VBA, podemos utilizar os dois formatos vlidos:me!NomedoCampo.BackColor = 13952764'oume!NomedoCampo.BackColor = RGB(252,230,212)Segue a funo que converte o valor HTML para o valor Decimal, vlido no VBA:Public Function fncCorDec(strHTML As String) As LongDim p(2) as integerp(0) = CInt("&h" & Mid(strHTML, 2, 2))p(1) = CInt("&h" & Mid(strHTML, 4, 2))p(2) = CInt("&h" & Mid(strHTML, 6, 2))fncCorDec = RGB(p(0),p(1),p(2))End FunctionExemplo de uso da funo:me!NomeDoCampo.backColor = fncCorDec("#FCE6D4")Dica 35 - Desmarcar itens selecionados em um controle ListboxObserve, na imagem abaixo, um item da lista selecionado pelo clique do mouse.

Para remover a marcao da lista, basta atribuir um valor negativo ao controle Listbox. Neste exemplo, quando o campoFiltrarrecebe o foco, a lista desmarcada.Private Sub txtFiltro_GotFocus()Me!Lista = -1End SubAgora observe o controle Listbox abaixo, configurado paraSelees Mltiplas:

A tcnica para desmarcar a lista passar o valor da propriedadeSelected(item)da Listbox paraFalse.Private Sub txtFiltro_GotFocus()Dim n As Integer'------------------------------------------------------'Percorre a lista do ltimo item para o primeiro item'------------------------------------------------------For n = (Me!Lista.ListCount - 1) To 0 Step -1 '------------------------------ 'Vai desmarcando item por item '------------------------------ Me!Lista.Selected(n) = FalseNextEnd SubSe desejar marcar todos os itens da lista, atravs de um boto, basta passar o valor da propriedadeSelected(item)paraTrue.Private Sub btSelecionaTudo_Click()Dim n As IntegerFor n = (Me!Lista.ListCount - 1) To 0 Step -1 '------------------------------ 'Vai marcando item por item '------------------------------ Me!Lista.Selected(n) = TrueNextMe!txtFiltro.SetFocusEnd SubDica 36 - Exibir relatrio dos itens selecionados de uma ListBoxObserve, na imagem abaixo, os itens selecionados na Listbox:

Foram selecionados os itens de nmeros 2, 19, 21 e 24. Podemos realizar a filtragem do relatrio atravs destes nmeros selecionados, utilizando o operadorIN(), conforme o cdigo apresentado abaixo:Docmd.OpenReport "rltFrutas",acViewPreview ,,"IdFruta in(2,19,21,24)"Ou podemos tambm selecionar pelo nome da fruta (campo do tipo string):Dim strFiltro as stringstrFiltro ="NomeFruta IN('Abacate','banana','laranja,'melo')"Docmd.OpenReport "rltFrutas",acViewPreview ,,strFiltroA propriedade do controle Listbox que nos permite capturar os itens selecionados aItemsSelected. E para percorrer e capturar cada um dos itens selecionados, fazemos uso do laoFor Each.O cdigo exemplo abaixo monta a lista do operadorIN()com o nmeros exclusivos.Private Sub btRelatorio_Click()Dim strFiltro As String, Sel As Variant, j As Boolean

strFiltro = "in("'----------------------------------------'Percorre cada item selecionado da lista'----------------------------------------For Each Sel In Me!Lista.ItemsSelected '------------------------------------------------------- 'Adiciona o item selecionado da lista no operador IN() '------------------------------------------------------- strFiltro = strFiltro & Me!Lista.Column(0, Sel) & "," j = TrueNextstrFiltro = Mid(strFiltro, 1, len(strFiltro) - 1) & ")"strFiltro = "idfruta " & strFiltro

If j = False Then Exit Sub 'Aborta, caso no haja item selecionadoDoCmd.OpenReport "rltFrutas", acViewPreview, , strFiltroEnd SubNota 1:Para poder selecionar mltiplos itens em um controle Listbox, altere a propriedadeSelees MltiplasparaSimples.Nota 2: Baixe o exemplo, aqui apresentado,neste meu artigo.Dica 37 - Como atrasar um cdigo sem usar APINadica 13foi apresentado a APIsleep(), com o objetivo de atrasar a execuo de uma rotina. Uma alternativa de cdigo para a mesma finalidade fazermos uso da funotimer()do Access. Observe o cdigo:Public Sub fncAguardar(lngMilesegundos)Dim varStartvarStart = Timer 'Tempo inicialDo While Timer < varStart + (lngMilesegundos / 1000) DoEvents 'Libera outros processosLoopEnd SubComo teste, experimente utilizar o procedimento antes da abertura de um relatrio:call fncAguardar(5000) 'Aguarda por 5 segundosDocmd.OpenReport "NomeRelatrio", acViewPreviewDica 38 - Configurar atalho do seu aplicativo no desktop para realizar algumas tarefasVeja, na imagem abaixo, um exemplo de atalho simples, criado no Desktop:

Observe o campoDESTINOdo atalho. Neste campo podemos introduzir um ou mais comandos, com o objetivo de se executar tarefas especficas na inicializao.Destino : c:\Maestro\Open_v3.accdr/comando/comandoVeja, na tabela abaixo, alguns destes comandos:/ExclAbre o aplicativo para uso exclusivo. Utilize para troca de senha.

/RoAbre o aplicativo para uso apenas como leitura.

/RepairRepara o Banco de Dados e depois fecha o Access.

/CompactCompacta e Repara o aplicativo. Utilize para realizar Backup.

/X NomeDaMacroExecuta uma macro na partida. No use espao no nome da macro.

/DecompileManuteno e limpeza do cdigo VBA. Faa um backup de segurana do seu Banco de Dados, antes de aplicar este comando.

/RuntimeInicia o Access no modo Runtime para testes ou para evitar que o usurio entre no modo estrutura.

/NoStartupNo mostrar a caixa de dilogo de abertura do Access

Com o comando/Compactpodemos criar um atalho para realizar um backupDESTINO: c:\maestro\maestro_be.accdb/compactd:\maestro\backup\maestro_be_bkp.accdbCuidado com os nomes compostos, contendo espaos. Se este for o seu caso, dever acrescentar as aspas, conforme exemplo na linha abaixo:DESTINO:"c:\Sua Pasta\Seu Bd.accdb"/compactd:\SuaPasta\backup\SeuBd_bkp.accdbObserve que a linha aonde se informa o destino do backup (d:\SuaPasta\backup\SeuBd_bkp.accdb) no pode conter espao nos nomes, pois acarretar em erro na execuo do atalho.Nota:Procure no utilizarespaosno nome das pastas e no nome dos seus aplicativos. Exemplo de nomes compostos sem o uso de espaos:c:\UsandoAccess\ProtecMaestro.accdbPode realizar o backup para uma pastacompartilhada,em outra mquina na rede.DESTINO:"c:\Sua Pasta\Seu Bd.accdb"/compact\\NomeMquina\SuaPasta\backup\SeuBd.accdbSe o IP da mquina for fixo, pode ser usado tambm.DESTINO: c:\SuaPasta\SeuBd.accdb/compact\\192.168.1.200\SuaPasta\backup\SeuBd.accdbDica 39 - Como abrir o Access na verso correta, tendo duas ou mais verses na mquina ?Vamos supor que voc tenha instalado em uma mquina o Access 2010 e o Access 2007 Runtime e deseja que seu aplicativo abra sempre na verso runtime 2007. A tcnica para isso a de criar um atalho do Executvel, da verso desejada.Observe na imagem abaixo, que ao selecionar o executvel do Access Runtime 2007 com o boto da direita do Mouse, temos a opoEnviar para >Ambiente de trabalho (criar atalho).

Abrindo a propriedade do atalho criado, temos a linha completa de chamada do executvel do Access Runtime no campo DESTINO. Isso garante que o Access Runtime 2007 seja aberto, mesmo que o Access 2010 esteja como padro.

Basta acrescentar, depois da linha do executvel, o caminho e o nome do aplicativo a ser aberto. Observe a parte sublinhada:

Se o caminho ou nome do seu aplicativo contiver espao, deve utilizar as aspas.DESTINO: "...\MSACCESS.EXE""c:\Sua pasta\Seu BD.accdb"Dica 40 - Teclas de atalhos para botesObserve, na imagem abaixo, o nome&Salvar na propriedade Legenda do boto btSalvar:

A smbolo&na frente do caractere desejado, determina o atalho especfico para o boto. Observe a letra S sublinhada no boto.

Para acionar o boto, basta manter pressionada a teclaALTe imediatamente pressionar a teclaS.Refaa o atalho do boto para que seja acionado pela letra "a" (S&alvar) e faa um teste. (ALT + a)Dica 41 - Manipulando strings com a classe StringsObserve, na imagem abaixo, a classe Strings e seus Membros. Lista obtida atravs do Pesquisador de Objetos do VBA.

Veja alguns exemplos de uso desta classe pelo Access:FunoDescrioExemploRetorno

AscRetorna o valor numrico ANSI do caractere como um Integer.Asc("C")67

ChrRetorna o caractere correspondente ao valor numrico ANSI como um string.Chr(67)Chr(10)CAvano delinha

FormatFormata uma expresso de acordo com os strings de formato apropriado.Format(Date,"dd-mm-yy")12-06-14

InStrRetorna a posio de uma string dentro da outra.Instr("ABCDE","D")4

LcaseRetorna o valor de string com letras minsculas.Lcase("ABCD")abcd

LeftRetorna os caracteres da esquerda de uma string.left("ABCDE",2)AB

LenRetorna o nmero de caracteres em uma string como tipo Long.len("ABCDE")5

LTrimRemove os espaos iniciais da string.LTrim(" ABCD")ABCD

MidRetorna uma parte de uma string.Mid("ABCDE",2,3)Mid("ABCDE",2)BCDBCDE

RightRetorna os caracteres da direita de um string.Right("ABCDE",2)DE

RTrimRemove os espaos finais de uma string.RTRim("ABCD ")ABCD

SpaceRetorna uma string contendo um nmero especfico de espao.Space(2) & "ABCD"__ABCD

strConverte o valor numrico de qualquer tipo de dados para uma string.str(123,45)123,45

StringRetorna uma string contendo os caracteres especficos repetidos.string(5,"A")AAAAA

TrimRemove os espaos iniciais e finais de uma string.trim(" ABCDE ")ABCDE

UCaseRetorna a verso de uma string com letras maisculasUCase("abcDe")ABCDE

ReplaceSubstitui uma parte por outra em uma sentena.Replace("ABC","B","2")A2C

SplitSepara uma sentena com base em um ou mais caractere determinado.j=Split("ab cd"," ")j(0)::> abj(1)::> cd

JoinForma uma nica string de uma matriz.k(0)='ab'k(1)='cd'Join(k," ")ab cd

WeekdayNameRetorna uma string, indicando o dia da semana especificado.WeekdayName(1)WeekdayName(3)DomingoTera

Saiba como explorar o HELP do VBA atravsdestaminha vdeo-aula.

Bom estudo!