Usuário com melhor resposta
Macro excel data sem barra

Pergunta
-
Prezados:
Utilizo uma macro do excel para digitar as datas sem digitar as barras (“/”).
Caso a data seja digitada com as barras, aparece uma mensagem de erro.
Acontece que qualquer data dentro do período de 29/05/82 a 24/11/1990 (não sei se com outros períodos também acontece) que for digitada com as barras, não dá erro e a mensagem de erro não aparece, e o excel entende a data inserida como um número.
Caso seja desabilitado o “Case 5” da macro, este problema não acontece, mas ai o excel não reconhece as datas que começam com zero.
Teria como resolver este problema?
Encontrei outra macro bem parecida com a que utilizo, mas também acontece o mesmo problema.
MACRO QUE UTILIZO:
Public Sub Worksheet_Change(ByVal Target As Range)
'Função para entrar Datas sem digitar as "/"
Dim DateStr As String, C1, C2
Select Case Target.Cells.Count
Case Is > 1
For Each C1 In Range(Target.Address)
For Each C2 In Range("A1:A25")
If C1.Address = C2.Address Then
If FLAG Then
Selection.Delete
FLAG = Not FLAG
Exit Sub
End If
Exit Sub
End If
Next C2
Next C1
Exit Sub
Case Else
If Application.Intersect(Range(Target.Address), _
Range("A1:A25")) Is Nothing Or _
Target.Value2 = "" Then Exit Sub
End Select
On Error GoTo EndMacro
With Target
If .HasFormula = False Then
Select Case Len(.Formula)
Case 1 'ex: 1 = 00/00/01
DateStr = "01/01/0" & .Formula
Case 2 'ex: 12 = 00/00/12
DateStr = "01/01/" & .Formula
Case 3 'ex: 123 = 00/01/23
DateStr = "01/0" & Left(.Formula, 1) & "/" & Right(.Formula, 2)
Case 4 'ex: 1234 = 00/12/34
DateStr = "01/" & Left(.Formula, 2) & "/" & Right(.Formula, 2)
Case 5 'ex: 12345 = 01/23/45
DateStr = Left(.Formula, 1) & "/" & Mid(.Formula, 2, 2) & "/" & Right(.Formula, 2)
Case 6 'ex: 123456 = 12/34/56
DateStr = Left(.Formula, 2) & "/" & Mid(.Formula, 3, 2) & "/" & Right(.Formula, 2)
Case 7 'ex: 1234567 = 12/34/567
DateStr = Left(.Formula, 2) & "/" & Mid(.Formula, 3, 2) & "/" & Right(.Formula, 2)
Case 8 'ex: 12345678 = 12/34/5678
DateStr = Left(.Formula, 2) & "/" & Mid(.Formula, 3, 2) & "/" & Right(.Formula, 2)
End Select
Application.EnableEvents = False
.Formula = DateValue(DateStr)
End If
End With
GoTo Fim
EndMacro:
Target.Value = "" 'limpa a célula
Range(Target.Address).Select
MsgBox "As datas deverão ser inseridas no formato ddmmaa, sem as barras.", vbInformation, "DATA INVÁLIDA !!!!!"
Fim:
Application.EnableEvents = True
End Sub
MACRO QUE ENCONTREI NA INTERNET:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim DateStr As String
On Error GoTo EndMacro
If Intersect(Target, Range("A1:A25")) Is Nothing Then Exit Sub
If Target.Cells.Count > 1 Then Exit Sub
If Target.Value = "" Then Exit Sub
Application.EnableEvents = False
With Target
If .HasFormula = False Then
Select Case Len(.Formula)
Case 5
DateStr = Left(.Formula, 1) & "/" & Mid(.Formula, 2, 2) & "/" & Right(.Formula, 2)
Case 6
DateStr = Left(.Formula, 2) & "/" & Mid(.Formula, 3, 2) & "/" & Right(.Formula, 2)
Case Else
Err.Raise 0
End Select
.Formula = DateValue(DateStr)
End If
End With
Application.EnableEvents = True
Exit Sub
EndMacro:
MsgBox "As datas deverão ser inseridas no formato ddmmaa, sem as barras.", vbInformation, "DATA INVÁLIDA !!!!!"
Range(Target.Address).ClearContents
Application.EnableEvents = True
End Sub
Grato
AdrianoPires
Respostas
-
Não utilize esse OnEntry.
Não sei se entendi muito bem sua pergunta, mas acho que seria algo como:
Private Sub Worksheet_Change(ByVal Target As Range) If Intersect(Target, Range("A1:C30")) Is Nothing Then Exit Sub If Target.Cells.Count > 1 Then Application.Undo MsgBox "Change only one cell at once." Exit Sub End If If Not IsNumeric(Target) Then Target.ClearContents MsgBox "Enter a number." Exit Sub End If End Sub
Felipe Costa Gualberto - http://www.ambienteoffice.com.br
- Marcado como Resposta AdrianoPires sexta-feira, 20 de março de 2015 14:55
- Não Marcado como Resposta AdrianoPires segunda-feira, 23 de março de 2015 14:18
- Marcado como Resposta AdrianoPires segunda-feira, 23 de março de 2015 14:18
Todas as Respostas
-
-
Olá Adriano, não analisei nenhum dos códigos, mas gostaria de te dar uma dica sobre algo que acho mais interessante. Nosso amigo Felipe Gualberto, aqui do forum, desenvolveu um calendário pop-up muito bacana e eu quando necessito desenvolver planilhas com preenchimento de dadas, agora dou preferência por utilizar este calendário, fazendo a associação dele com o evento selection_change da planilha utilizando a função intersect para definir os ranges de data. Fica uma solução muito bacana para aplicação da data.
Entre no link abaixo e veja se essa não seria uma solução mais interessante para você.
http://www.ambienteoffice.com.br/officevba/calendario_pop-up/
Abraços!
Rafael Kamimura
-
-
-
Olá Felipe, Obrigado pela atenção.
É isso mesmo, e não pode ser com máscara, pois uso as datas para fazer cálculos, por isso tem que ser por macro.
Os dois códigos que postei acima fazem isso, porém como disse, para datas dentro do período de 29/05/82 a 24/11/1990 (não sei se com outros períodos também acontece), se for digitada a expressão com as barras, não dá erro e a mensagem de erro não aparece, e o excel entende a data inserida como um número.
Será quem tem como dar um jeito nisso?
Já pensei se seria possível implementar os códigos acima para entrada de números apenas, assim se fosse digitada alguma data com as barras o erro também mostraria a mensagem box.
Grato
AdrianoPires
-
-
-
Adriano, esse problema é muito complicado de resolver porque em células que estão formatadas como data, ao entrar um número de série como 031119, o Excel irá converter esse número de série automaticamente na data 13/03/85.
É possível ler o valor 031119 acessando a propriedade Target.Value2, e é possível acessar o valor 13/03/85 acessando a propriedade Target.Value. No entanto, não é possível saber se o usuário digitou, intencionalmente 031119 ou 13/03/85, explicando o comportamento inesperado da rotina.
Esse problema só pode ser resolvido se no intervalo A1:A25 as células estiverem formatadas como texto e for feita uma adaptação na macro, mas a solução é insatisfatória porque as datas irão ficar armazenadas como texto, e não valores. Com isso, você não poderá fazer uso delas para operações e filtros, a não ser que as multiplique por 1 no que for precisar delas, por exemplo.
---
Minha sugestão é esquecer a ideia de querer transformar o valor de uma célula digitada, pois isso é uma péssima prática no Excel. Esqueça o VBA nesse caso e adote uma solução mais simples: coloque uma fórmula na coluna B que irá retornar a data com base no formato ddmmaa digitado na coluna A.
Felipe Costa Gualberto - http://www.ambienteoffice.com.br
-
Felipe
Entendi e agradeço a atenção, mas seria possível unir o código abaixo? Assim, se acidentalmente fosse digitada uma data com as barras a mensagem de erro apareceria.
Observe que o código abaixo está montado para funcionar na coluna "C", teria que alterar para o intervalo "A1:A25".
Sub Auto_Open()
Sheets("Plan1").OnEntry = "numbers"
End Sub
Sub numbers()
If ActiveCell.Column = 3 And Not IsNumeric(ActiveCell.Value) Then
MsgBox "Enter a number."
ActiveCell.Value = "" ' Clears contents of active cell.
End If
End Sub
GratoAdrianoPires
-
-
Felipe,
Eu quero digitar 030597 (data sem barras) e o resultado na célula seja 03/05/97 (data com barras), ou seja, quero digitar a data sem as barras e o código incluir as barras. Mas como disse anteriormente, não pode ser por máscara, tem que ser via código, pois utilizo as datas em cálculo.
Os códigos acima funcionam desde que sejam digitadas as datas sem barras, porém pode ocorrem das pessoas que utilizam a planilha digitar com as barras e ai nem sempre aparece a mensagem de erro.
Foi o exemplo que eu dei.
Se você digitar 030597 o resultado na célula será 03/05/97 - então ok, é isso que quero.
Se você digitar 03/05/97 aparece a mensagem de erro - então ok, é isso que quero, pois foi digitado com as barras.
Mas se você digitar qualquer data do intervalo 29/05/82 a 24/11/1990 (não sei se com outros períodos também acontece), com as barras, não aparece a mensagem de erro - então está errado, não quero isso, quero que apareça a mensagem de erro.
Grato
AdrianoPires
-
"Mas se você digitar qualquer data do intervalo 29/05/82 a 24/11/1990 (não sei se com outros períodos também acontece), com as barras, não aparece a mensagem de erro - então está errado, não quero isso, quero que apareça a mensagem de erro."
Como eu disse, é impossível monitorar isso a não ser que as células da coluna A estejam formatadas como Texto, que na prática seria terrível.
---
Minha sugestão é você proibir usuários de digitar na coluna A, apenas na B. Na B, seria possível proibir entrada de datas com barras, e em A haveria uma fórmula que transformasse a cadeia numérica de B em data.
Felipe Costa Gualberto - http://www.ambienteoffice.com.br
-
Acho que não é uma solução boa, a planilha teria a coluna B com números iguais as datas da coluna A.
Seria possível incluir o código abaixo, para o intervalo A1:A25, assim só seria possível digitar números
Sub Auto_Open()
Sheets("Plan1").OnEntry = "numbers"
End Sub
Sub numbers()
If ActiveCell.Column = 3 And Not IsNumeric(ActiveCell.Value) Then
MsgBox "Enter a number."
ActiveCell.Value = "" ' Clears contents of active cell.
End If
End SubGrato
AdrianoPires
-
"Acho que não é uma solução boa, a planilha teria a coluna B com números iguais as datas da coluna A."
Sim, mas nesse caso, eu ocultaria a coluna A.
---
"Seria possível incluir o código abaixo, para o intervalo A1:A25, assim só seria possível digitar números"
Não, porque data, na verdade, é um número, então essa validação que você fez não funcionaria para sequências entradas com ou sem a \
Felipe Costa Gualberto - http://www.ambienteoffice.com.br
-
Felipe,
Me desculpe, mas não entendo tanto de excel e minha dúvida é:
O codigo para data sem barra funciona perfeitamente se for inseridas as datas sem barra - então ok.
O prolema só ocorre se for digitado as datas com barra.
O outro código que passei, o numbers, pelo que testei, se for digitado algo diferente de números, limpa a célula e aparece uma mensagem de erro - então ok.
Minha dúvida é :
Não seria possível unir os dois? Ou seja, primeiro o "numbers" verifica se só tem números, se sim, o "data sem barra" converte o número inserido na data com barras.
De qualquer forma como ficaria o código numbers para um intervalo de células e nao por coluna?
Grato
AdrianoPires
-
"Não seria possível unir os dois? Ou seja, primeiro o "numbers" verifica se só tem números, se sim, o "data sem barra" converte o número inserido na data com barras. "
Não, é impossível. Se uma célula estiver formatada como data e você digitar, por exemplo 010103, o Excel irá converter essa sequência para 29/08/1927 automaticamente. Logo, a pergunta é: como o Excel saberá que você digitou 010103 ou 29/08/1927? Como essa conversão é feita antes de disparar o evento Worksheet_Change, não é possível responder essa pergunta, a não ser que as células fiquem formatadas como Texto, havendo também o ônus de não se comportarem mais como datas.
Quando você quer que a rotina Numbers dispare? Sempre que se alterar uma célula ou ao entrar numa planilha? Já antecipo que em qualquer um dos casos, seu problema não será resolvido por causa das limitações explicadas acima.
Felipe Costa Gualberto - http://www.ambienteoffice.com.br
- Editado Felipe Costa GualbertoMVP, Moderator quinta-feira, 12 de março de 2015 10:35
-
Quando você quer que a rotina Numbers dispare? Sempre que se alterar uma célula ou ao entrar numa planilha? Já antecipo que em qualquer um dos casos, seu problema não será resolvido por causa das limitações explicadas acima.
Como não entendo muito, acho que deveria disparar quando entrasse um número no intervalo A1:a25.
Acho que mais ou menos assim: Como o código "data sem barra" funciona perfeitamente se todas as datas forem digitadas sem as barras, acho que o "numbers" deveria disparar antes, faz a verificação se só tem números, e se for só numeros, executa a "data sem barras"
Mas como disse entendo pouco, então não sei.
Grato
AdrianoPires
-
"o 'numbers' deveria disparar antes, faz a verificação se só tem números, e se for só numeros, executa a "data sem barras""
Acho que nos entendemos agora: não é possível o VBA saber se foi entrado um número ou uma data numa célula se a mesma estiver formatada como Data porque para o Excel números e datas são, essencialmente, a mesma coisa.
E volto a repetir: Minha sugestão é você proibir usuários de digitar na coluna A, apenas na B. Na B, seria possível proibir entrada de datas com barras, e em A haveria uma fórmula que transformasse a cadeia numérica de B em data. Oculte a coluna A.
Felipe Costa Gualberto - http://www.ambienteoffice.com.br
-
Entendi.
Prefiro deixar o código "data sem barra" e deixar claro para os usuários que se for digitado alguma data com barra poderá ter problemas.
Muito obrigado pela sua atenção, mas só por curiosidade e aprendizagem, como seria o código numbers para um intervalo, tipo A1:C30 ao invés de coluna?
Grato
AdrianoPires
-
Não utilize esse OnEntry.
Não sei se entendi muito bem sua pergunta, mas acho que seria algo como:
Private Sub Worksheet_Change(ByVal Target As Range) If Intersect(Target, Range("A1:C30")) Is Nothing Then Exit Sub If Target.Cells.Count > 1 Then Application.Undo MsgBox "Change only one cell at once." Exit Sub End If If Not IsNumeric(Target) Then Target.ClearContents MsgBox "Enter a number." Exit Sub End If End Sub
Felipe Costa Gualberto - http://www.ambienteoffice.com.br
- Marcado como Resposta AdrianoPires sexta-feira, 20 de março de 2015 14:55
- Não Marcado como Resposta AdrianoPires segunda-feira, 23 de março de 2015 14:18
- Marcado como Resposta AdrianoPires segunda-feira, 23 de março de 2015 14:18
-
-
Prezados,
Outro colega respondeu minha dúvida me enviando uma sugestão, recebi o email mas a mensagem não aparece aqui nas respostas. Porque?
O usuário foi o M_A_L que postou:
Amigo.
Por acaso já tentou colocar a data desta forma?
Private Sub Worksheet_Change()
If Len(activecell) = 2 Or Len(activecell) = 5 Then
activecell.Text = activecell.Text & "/"
SendKeys "{End}", True
End If
End Sub
Depois coloca no codigo um
if len(activecell.value)<>10 then
activecell.value=""
activecell.setfocus
end if
Se quiser o ano com dois digitos, pode definir as carateristicas da célula ativa para 8 carateres.
Em Userform, sei que dá para fazer pois eu utilizo dessa forma. Diretamente na folha não sei, mas talvez valha a pena tentar. Assim você digita apenas números e o VBA coloca a barra "/".
Tente adaptar ao seu caso e na dúvida, temos aqui excelentes pessoas que podem dar uma mãozinha nisso.
Será que dá para tentar?
cumprimentos
M_A_L
Agradeço a ajuda, mas como não entendo bem não sei se seria possível.
Alguém pra responder?
AdrianoPires
-
-
-
-
-
Boa noite, Adriano.
Como o Felipe disse e bem, a resposta foi eliminada, pois parece que não era isso que pretendias.
Ao utilizar o código que enviei, as barras apareceriam no Form e no momento de digitar os números, embora não seja necessário escrevê-lo.
Por não ser o que pretendias e que no início entendi erradamente, eliminei a ajuda a este post.
Mas estás ser acompanhado pelo Felipe e se souberes colocar as tuas dúvidas e o problema tiver solução, então o Felipe encontra.
Cumprimentos
M_A_L