none
Como saber a localização de uma célula do excel após digitar determinado valor através do VBA RRS feed

  • Pergunta

  • Pessoal, boa noite!

    Espero que alguém possa me ajudar...

    Estou criando um programa pelo UserForm do Excel. Neste programa as pessoas colocam informações de determinado equipamento que está indo à manutenção, ao lançar este dado para a planilha, automaticamente coloco um número de registro para esta informação com auto-incremento.

    Depois de um tempo, o mecânico responsável irá atualizar está planilha, ele vai estar em uma outra janela de Userform dentro da mesma planilha, colocar no UserForm o número do registro da manutenção (Aqui acho que o VBA deveria procurar qual linha que este registro está) e colocar o Status de "Concluído" para a coluna 7 daquele registro.

    É uma coisa simples, porém nunca vi uma fórmula que encontre o valor da linha. Alguém pode me ajudar?

    Seria mais ou menos assim no algoritmo:

    -a variável X contém o número da LINHA correspondente ao valor digitado no "TexBox1"

    - digo ao VBA que: linha = X

    - aí vem a fórmula que eu não sei -- altere a coluna 7 com o valor do TextBox2 na linha X <-- essa linha será o número que foi localizado pelo protocolo digitado no TextBox1...

    Bom, essa é minha ideia pode ser que tenha um jeito mais fácil...

    Alguém pode me ajudar?

    sábado, 9 de agosto de 2014 01:24

Respostas

  • Olá, boa noite!

    Tente algo do tipo:

    Dim pPlan As Worksheet
    
    Set pPlan = Plan1       'Escolha a planilha desejada
    
    Li = 2      'Linha inicial com os Dados
    Ci = 1      'Coluna de busca
    Cd = 7      'Coluna para resultado
    
    Registro = TextBox1.Value
    Valor = TextBox2.Value
    
    Lf = pPlan.Cells(Rows.Count, Ci).End(xlUp).Row   'Analisa o nº da última linha escrita
    
    
    For i = Li To Lf
        If pPlan.Cells(i, Ci).Value2 = Registro Then
            nLinha = i
            Encontrado = 1
            Exit For
        End If
    Next i
    
    If Encontrado = 1 Then
        pPlan.Cells(nLinha, Cd).Value2 = Valor
    Else
        MsgBox "Não existe o identificador informado!", vbCritical, "Erro"
    End If
    Abraço.


    Filipe Magno

    • Marcado como Resposta Anderson Thuler segunda-feira, 11 de agosto de 2014 15:45
    sábado, 9 de agosto de 2014 01:51
  • Consegui Felipe...

    Achei o código!!!

    Dim lRow As Long
    Set ws = Worksheets("Relatório")
    Data = Format(txtDate.Value, "mm/dd/yyyy")

    lRow = ws.Columns(1).Find(what:=ComboBox1.Value).Row

    Tinha uma planilha exemplo que baixei da WEB e nela onde está ws.Columns estava ws.cells

    O que fiz foi alterar por COLUMNS(1) e encontrar o que eu estou procurando naquela primeira coluna.

    Deu certo, só falta alguma coisa que eu quero agora.. é mudar o tipo de protocolo para formato "0001", "0002" etc e eu ter que digitar estes número para procurar.. porque quando estiver nas casas 10, 11 e assim por diante ele vai se confundir se caso eu digitar procure "1" porque 10, 11 e assim por diante pode conter o número 1 por exemplo e dar confusao...

    Você me entende?

    E a segunda coisa que gostaria é:

    Caso não exista um protocolo, exiba uma mensagem assim "O protocolo não existe, verifique se está correto"

    Vou postar a planilha, só que estou com vergonha porque não tenho experiência então tenho certeza que está uma bagunça os códigos. acho que só eu te explicando para você entender :/

    mas vou postar aqui!! hehehe

    • Marcado como Resposta Anderson Thuler terça-feira, 12 de agosto de 2014 21:34
    domingo, 10 de agosto de 2014 02:26
  • Olá, boa tarde.

    Primeiramente não se envergonhe! Acredite, ninguém nasce sabendo. Para o seu problema, algumas dicas para melhorar seu código:

    • Evite usar "Windows("Equipamentos.xlsm")". Caso seu arquivo seja renomeado (o que relativamente comum) seu código deixará de funcionar. Além do que, na maioria dos casos esse é um código desnecessário quando o arquivo de destino é o mesmo onde está a macro. Caso ainda assim precise usar, sugiro algo como "ThisWorkbook".
    • Para modificar um dado em uma planilha primeiro atíve-a:
    Sheet1.Activate
    • Depois pode retornar à planilha anterior. Para isso sugiro que primeiro verifique o nome da aba ativa e em seguida reexíba-a:
    pAptual = ActiveSheet.Name
    Sheet1.Activate
    
    '(...)
    
    Sheets(pAtual).Activate
    • Caso seja uma aba oculta, desative a atualização de tela antes (não funciona no modo depuração). Além de deixar seu código mais rápido (muuuuuito mais rápido!), o usuário não perceberá a transição.
    'Início do código:
    ScrUp = Application.ScreenUpdating          'Verifica a situação atual
    If ScrUp Then Application.ScreenUpdating = False
    
    '(...)
    
    pAptual = ActiveSheet.Name
    Sheet1.Activate
    
    '(...)
    
    Sheets(pAtual).Activate
    
    '(...)
    
    'Fim do Código:
    If ScrUp And Ac Then Application.ScreenUpdating = True
    • Não aconselho usar a função de busca que vc sugeriu exatamente pelo motivo que vc citou. Vc até poderia tentar contornar definindo para buscar pelo conteúdo integral da célula, mas ainda assim eu sugiro usar o código que já te passei. Ele faz exatamente isso (já está pronto).
    • Quanto à mensagem, se olhar bem, também já está implementado no código que te passei. Você precisa colá-lo dentro de alguma "Sub" e associar a ele o comando desejado (provavelmente vc precisará fazer pequenas adaptações, mas o código principal está pronto).
    • Por fim, para não ter que exibir as planilhas ao usuário, o mais simples é ocultar todas as abas e deixar visível apenas uma aba de apresentação, com os botões ou imagens necessárias para executar seu projeto.
    • Para impedir que os usuários reexibam as abas ocultas, oculte-as pelo VBA com o atributo Very Hidden (vc pode ocultá-las também pelas propriedades dos objetos no VBA, bastando pressionar F4 e escolher as planilhas desejadas). Em seguida proteja seu projeto VBA com senha:
    Sheet1.Visible = xlSheetVeryHidden

    Acho que com essas dicas vc resolve seu problema.

    Abraço.


    Filipe Magno

    • Marcado como Resposta Anderson Thuler segunda-feira, 11 de agosto de 2014 15:45
    domingo, 10 de agosto de 2014 18:37
  • Boa noite Anderson.

    Desculpe, não fui claro o suficiente. Para ocultar a janela do projeto em questão vc precisa usar o "Windows", mas pode usar o "ThisWorkbook" para apontá-lo. Como vc mesmo descreveu, o "ThisWorkbook" não tem o método "visible". Então, nesse caso, use algo como:

    Windows(ThisWorkbook.Name).Visible = True

    Abraço.


    Filipe Magno

    • Marcado como Resposta Anderson Thuler quarta-feira, 13 de agosto de 2014 00:38
    terça-feira, 12 de agosto de 2014 22:31

Todas as Respostas

  • Olá, boa noite!

    Tente algo do tipo:

    Dim pPlan As Worksheet
    
    Set pPlan = Plan1       'Escolha a planilha desejada
    
    Li = 2      'Linha inicial com os Dados
    Ci = 1      'Coluna de busca
    Cd = 7      'Coluna para resultado
    
    Registro = TextBox1.Value
    Valor = TextBox2.Value
    
    Lf = pPlan.Cells(Rows.Count, Ci).End(xlUp).Row   'Analisa o nº da última linha escrita
    
    
    For i = Li To Lf
        If pPlan.Cells(i, Ci).Value2 = Registro Then
            nLinha = i
            Encontrado = 1
            Exit For
        End If
    Next i
    
    If Encontrado = 1 Then
        pPlan.Cells(nLinha, Cd).Value2 = Valor
    Else
        MsgBox "Não existe o identificador informado!", vbCritical, "Erro"
    End If
    Abraço.


    Filipe Magno

    • Marcado como Resposta Anderson Thuler segunda-feira, 11 de agosto de 2014 15:45
    sábado, 9 de agosto de 2014 01:51
  • Se você já tem a linha e a coluna, não seria apenas atribuir o valor?

    Range("G" & linha) = TextBox2.value

    Ou 

    Cells(linha, 7) = TextBox2.value

    Att.


    sábado, 9 de agosto de 2014 17:32
  • Então, eu queria fazer um outro Userform...

    Dentro deste Userform eu iria deixar uma caixa de pesquisa e colocaria digite o número do protocolo...

    E depois do protocolo encontrado, colocaria uma caixa dizendo, qual o Status para ser alterado desse protocolo...

    Como cada registro/protocolo fica em linhas diferentes, fica difícil eu definir para o userform uma coluna específica... Por este motivo quero encontrar a linha encontrado pela procura do protocolo e só depois de encontrado aquela linha, ele ir na coluna 7 e atualizar aquele campo com o Status que o usuário definiu... Entende?

    Não sei se estou sendo muito claro com esta ideia...

    sábado, 9 de agosto de 2014 21:55
  • Olá, boa noite!

    Você testou a solução que propus anteriormente? Ela faz exatamente isso: primeiro encontra o número da linha e depois altera. Exatamente como vc pediu.

    Ainda não funciona?

    Abraço.


    Filipe Magno

    sábado, 9 de agosto de 2014 22:06
  • Muito obrigado pela ajuda pessoal.

    Felipe, eu ia responder que eu iria verificar sua solução, mas não consegui naquele momento postar a resposta.

    Vou testar agora e já te falo.

    domingo, 10 de agosto de 2014 00:27
  •    If pPlan.Cells(i, Ci).Value2 = Registro Then

    Felipe, esse Value2 que sublinhei na formula acima, está certo mesmo? É que sou novo no VBA...

    Eu sempre usei .Value mas nunca havia visto value2

    Pode me explicar caso esteja certo?

    domingo, 10 de agosto de 2014 00:36
  • Teria como mandar a planilha para você ver?

    Não estou conseguindo....

    domingo, 10 de agosto de 2014 01:35
  • Olá!

    Está correto sim! Para troca de dados com a planilha existem as duas formas, e elas funcionam de maneira similar para a maioria dos casos. Entretanto, utilizar "Value" em algumas situações pode acarretar em erros indesejáveis: para o caso de números formatados como moeda ou hora, por exemplo, ocorre um truncamento nas casas decimas (acho que em 4 casas), o que pode em alguns casos, provocar erros consideráveis. Além disso, em algumas situações, "Value2" é mais rápido que "Value".

    Ou seja, a menos que tenha um motivo especial para usar "Value", sugiro que sempre utilize "Value2".

    Abraço.


    Filipe Magno

    domingo, 10 de agosto de 2014 01:35
  • Coloque-a no OneDrive ou SendSpace e cole o link aqui.

    Assim que der dou uma olhada.

    Abraço.


    Filipe Magno

    domingo, 10 de agosto de 2014 01:38
  • Consegui Felipe...

    Achei o código!!!

    Dim lRow As Long
    Set ws = Worksheets("Relatório")
    Data = Format(txtDate.Value, "mm/dd/yyyy")

    lRow = ws.Columns(1).Find(what:=ComboBox1.Value).Row

    Tinha uma planilha exemplo que baixei da WEB e nela onde está ws.Columns estava ws.cells

    O que fiz foi alterar por COLUMNS(1) e encontrar o que eu estou procurando naquela primeira coluna.

    Deu certo, só falta alguma coisa que eu quero agora.. é mudar o tipo de protocolo para formato "0001", "0002" etc e eu ter que digitar estes número para procurar.. porque quando estiver nas casas 10, 11 e assim por diante ele vai se confundir se caso eu digitar procure "1" porque 10, 11 e assim por diante pode conter o número 1 por exemplo e dar confusao...

    Você me entende?

    E a segunda coisa que gostaria é:

    Caso não exista um protocolo, exiba uma mensagem assim "O protocolo não existe, verifique se está correto"

    Vou postar a planilha, só que estou com vergonha porque não tenho experiência então tenho certeza que está uma bagunça os códigos. acho que só eu te explicando para você entender :/

    mas vou postar aqui!! hehehe

    • Marcado como Resposta Anderson Thuler terça-feira, 12 de agosto de 2014 21:34
    domingo, 10 de agosto de 2014 02:26
  • http://1drv.ms/1sKDysu

    Está uma zona.. conforme estou aprendendo estou aperfeiçoando.

    Na minha opinião está muito bagunçada e simples demais... queria deixar ela nos Userforms do que exibir dados na planilha. Fica meio estranho...

    Eu queria aprender a inserir os dados na planilha sem que ela esteja ativa visivelmente... quando faço isso com ela oculta me retorna erro.

    Mas enfim espero que eu consiga ir aperfeiçoando.

    E se puder me ajudar eu ficarei muito contente...

    Abraços!!

    domingo, 10 de agosto de 2014 02:35
  • Olá, boa tarde.

    Primeiramente não se envergonhe! Acredite, ninguém nasce sabendo. Para o seu problema, algumas dicas para melhorar seu código:

    • Evite usar "Windows("Equipamentos.xlsm")". Caso seu arquivo seja renomeado (o que relativamente comum) seu código deixará de funcionar. Além do que, na maioria dos casos esse é um código desnecessário quando o arquivo de destino é o mesmo onde está a macro. Caso ainda assim precise usar, sugiro algo como "ThisWorkbook".
    • Para modificar um dado em uma planilha primeiro atíve-a:
    Sheet1.Activate
    • Depois pode retornar à planilha anterior. Para isso sugiro que primeiro verifique o nome da aba ativa e em seguida reexíba-a:
    pAptual = ActiveSheet.Name
    Sheet1.Activate
    
    '(...)
    
    Sheets(pAtual).Activate
    • Caso seja uma aba oculta, desative a atualização de tela antes (não funciona no modo depuração). Além de deixar seu código mais rápido (muuuuuito mais rápido!), o usuário não perceberá a transição.
    'Início do código:
    ScrUp = Application.ScreenUpdating          'Verifica a situação atual
    If ScrUp Then Application.ScreenUpdating = False
    
    '(...)
    
    pAptual = ActiveSheet.Name
    Sheet1.Activate
    
    '(...)
    
    Sheets(pAtual).Activate
    
    '(...)
    
    'Fim do Código:
    If ScrUp And Ac Then Application.ScreenUpdating = True
    • Não aconselho usar a função de busca que vc sugeriu exatamente pelo motivo que vc citou. Vc até poderia tentar contornar definindo para buscar pelo conteúdo integral da célula, mas ainda assim eu sugiro usar o código que já te passei. Ele faz exatamente isso (já está pronto).
    • Quanto à mensagem, se olhar bem, também já está implementado no código que te passei. Você precisa colá-lo dentro de alguma "Sub" e associar a ele o comando desejado (provavelmente vc precisará fazer pequenas adaptações, mas o código principal está pronto).
    • Por fim, para não ter que exibir as planilhas ao usuário, o mais simples é ocultar todas as abas e deixar visível apenas uma aba de apresentação, com os botões ou imagens necessárias para executar seu projeto.
    • Para impedir que os usuários reexibam as abas ocultas, oculte-as pelo VBA com o atributo Very Hidden (vc pode ocultá-las também pelas propriedades dos objetos no VBA, bastando pressionar F4 e escolher as planilhas desejadas). Em seguida proteja seu projeto VBA com senha:
    Sheet1.Visible = xlSheetVeryHidden

    Acho que com essas dicas vc resolve seu problema.

    Abraço.


    Filipe Magno

    • Marcado como Resposta Anderson Thuler segunda-feira, 11 de agosto de 2014 15:45
    domingo, 10 de agosto de 2014 18:37
  • Nossa Felipe, parabéns pelo seu conhecimento!!! 

    Eu preciso aprender muito! :)

    Vou revisar este documento, para ser sincero eu não entendi o primeiro código que você mandou... Como disse eu estou começando agora a "fuçar"  no VBA nunca fiz curso... Então eu começo a ter uma ideia e vou no SR GOOGLE para tentar achar alguma resposta. Mas isto não me faz entender o como fazer e o porque uso determinada fórmula.

    Seria muito qualquer dia você fazer uma chamada no Skype para me explicar?  

    Se puder me ajudar ficaria muito grato!


    segunda-feira, 11 de agosto de 2014 15:44
  • Olá, boa noite.

    Obrigado pelo elogio.

    Sobre o Skype, sinceramente não acho uma ideia legal. Acho muito mais produtivo contribuir com postagens aqui no fórum, pois assim é possível trocar experiências com usuários mais qualificados e ainda ajudar a pessoas que podem compartilhar da mesma dúvida. Eu tenho aprendido muito por aqui, quando entrei não tinha a menor experiência com VBA. Fique à vontade para criar novos tópicos ou expor as dúvidas que ainda restam.

    Uma dica legal que te dou é acessar ao site do Felipe Costa Gualberto, que é um usuário bastante ativo nesse fórum: http://www.ambienteoffice.com.br/

    Abraço.


    Filipe Magno

    terça-feira, 12 de agosto de 2014 00:04
  • Okay Felipe, sem problemas agradeço mesmo as suas dicas, são de grande valia.

    Vou aprender  o que você me mandou, preciso também entender muito.

    Qualquer coisa então posto aqui caso eu não entenda.

    Abraços!


    Anderson

    terça-feira, 12 de agosto de 2014 12:53
  • Felipe, boa noite!

    Desculpa ter colocado algumas informações no meio da planilha meio cabulosa rsrs

    Eu acho que você deve ter lido, mas não se preocupe, aquilo foi pelo fato de eu estar cansado de realizar muitas correções e comecei a colocar qualquer coisa que veio na frente rsrs, e sem querer ao compartilhar com você eu esqueci de apaga-las.

    Agora vou trabalhar sério...

    Então, como sugerido por você, eu não consegui alterar a fórmula:

    WorkBook("Equipamentos.xlsm").visible = False

    POR:

    ThisWorkBook.visble = False

    Quando eu faço isso a seguinte mensagem aparece:

    Method or data member not found

    Eu devo colocar de alguma outra maneira?


    Anderson

    terça-feira, 12 de agosto de 2014 21:32
  • Boa noite Anderson.

    Desculpe, não fui claro o suficiente. Para ocultar a janela do projeto em questão vc precisa usar o "Windows", mas pode usar o "ThisWorkbook" para apontá-lo. Como vc mesmo descreveu, o "ThisWorkbook" não tem o método "visible". Então, nesse caso, use algo como:

    Windows(ThisWorkbook.Name).Visible = True

    Abraço.


    Filipe Magno

    • Marcado como Resposta Anderson Thuler quarta-feira, 13 de agosto de 2014 00:38
    terça-feira, 12 de agosto de 2014 22:31
  • Okay, você ta de nota 10 . Funcionou direitinho.

    Não querendo aproveitar, pois acho que já estou aproveitando de mais, como você aprendeu a mexer no VBA? Fez algum curso ou foi fuçando mesmo?

    Tem algum curso online, que você conheça e possa me indicar que te ajudou muito no VBA?

    Eu queria entender bem esses comandos.


    Anderson

    quarta-feira, 13 de agosto de 2014 00:44
  • Pode perguntar à vontade Anderson.

    Eu já tinha uma boa base de programação, mas nunca tinha trabalhado com VBA. Foi a partir de necessidades práticas que fui me aprofundando na linguagem. No início ia gravando as tarefas que precisava realizar e analisava os códigos gerados. Utilizei bastante a ajuda do próprio Excel e também muito as buscas na internet, mas não tive nenhum material formal.

    Esse fórum também me ajudou bastante, mas o principal acho que foi a curiosidade e dedicação, buscando sempre fazer da melhor forma possível, tentando deixar os códigos o mais flexível possível.

    O site que te passei tb é uma boa referência.

    Um grande abraço e sucesso.


    Filipe Magno

    quarta-feira, 13 de agosto de 2014 01:21
  • Felipe,  estou com problema nesta fórmula apresentada, após inserir este código no VB, eu realizo o teste e quando eu digito o valor que eu quero que encontre acontece o seguinte:

    Se eu digito algo que já existe, ele continua com o bloco de comandos inclusive roda a MSGBOX não existe o identificador informado.

    Se eu digito algo que não existe mesmo ele aparece a msgbox também... o que será que estou fazendo?

    Eu estou alterando as variáveis de acordo está no meu UserForm mas não sei o que está ocorrendo...


    Anderson

    quinta-feira, 14 de agosto de 2014 17:50
  • Olá Anderson.

    Note que a rotina apenas executa a linha da MsgBox se o registro não for encontrado:

    For i = Li To Lf
        If pPlan.Cells(i, Ci).Value2 = Registro Then
            nLinha = i
            Encontrado = 1
            Exit For
        End If
    Next i
    
    If Encontrado = 1 Then
        pPlan.Cells(nLinha, Cd).Value2 = Valor
    Else
        MsgBox "Não existe o identificador informado!", vbCritical, "Erro"
    End If

    Ou seja, o dado que você está procurando pode não corresponder ao dado existente na planilha. Uma possibilidade é vc estar comparando String com Número. Para verificar, basta rodar em modo depuração (pode ser pressionando F8, caso não tenha argumentos de entrada, ou colocando um Break Point antes do código acima e ir depurando com F8 quando atingir esse ponto, avaliando os valores atribuídos a cada variável). Uma dica é usar Shift + F9 para acompanhar valores de expressões mais facilmente.

    Caso não consiga depurar, poste um exemplo (se possível com a pasta de trabalho) que tento lhe ajudar mais.

    Abraço.


    Filipe Magno

    sexta-feira, 15 de agosto de 2014 00:40