Este fórum está sendo desativado

Depois de 9 anos, este fórum será desativado. Mas calma.... estamos migrando para uma comunidade no DISCORD. Junte-se a nós.

ENTRAR PARA DISCORD

Tópicos relacionados a códigos VBA, gravação de macros, etc.
  • Avatar do usuário
  • Avatar do usuário
Avatar do usuário
Por LeoHenrique
Posts Avatar
#45691
Bom dia a todos !

O código abaixo, é o mesmo que está na planilha em anexo. Ocorre que o código não está importando as datas, mesmo que duplicadas, na planilha destaquei onde ocorre.
Nosso colega "Osvaldomp" me ajudou muito com o mesmo, mas preciso de essa alteração.

No aguardo, e muito obrigado desde já.




Sub replicadatasFaturados()

Dim ref As Range, dat As Range, refAdd As String
'Seleciona todos
If [X7] <> "" Then Range("X7:X" & Cells(Rows.Count, 22).End(3).Row).Value = ""
For Each ref In Range("B7:B" & Cells(Rows.Count, 2).End(3).Row)
Set dat = Sheets("Faturados").[G:G].Find(ref.Value)
If Not dat Is Nothing Then
refAdd = dat.Address
Do
ref.Offset(, 22) = IIf(ref.Offset(, 22).Value = "", _
dat.Offset(, 19).Value, ref.Offset(, 20).Value & Chr(10) & dat.Offset(, 19).Value)
Set dat = Sheets("Faturados").[G:G].FindNext(After:=dat)
Loop While dat.Address <> refAdd
End If
Next ref
End Sub



Leandro Henrique
Você não está autorizado a ver ou baixar esse anexo.
Avatar do usuário
Por JCabral
Avatar
#45703
Não sera que em vez de ref.Offset(, 20).Value ser ref.Offset(, 22).Value ?
Mas ninguem melhor do que o Osvaldomp para ajudar.
Por osvaldomp
#45721
Nas alterações que você fez no código há duas falhas: uma delas é a que o JCabral apontou e a outra é na linha abaixo, destaque em vermelho
If [X7] <> "" Then Range("X7:X" & Cells(Rows.Count, 24).End(3).Row).Value = ""

No comando abaixo, além da correção que o JCabral apontou, eu acrescentei a formatação da primeira data que é inserida na célula pois o VBA inverte para mm/dd, já a partir da segunda data o VBA não inverte ... :?
Código: Selecionar todos
ref.Offset(, 22) = IIf(ref.Offset(, 22).Value = "", _
       Format(dat.Offset(, 19).Value, "mm/dd/yyyy"), ref.Offset(, 22).Value & Chr(10) & dat.Offset(, 19).Value)
Avatar do usuário
Por JCabral
Avatar
#45725
Caro Osvaldo

Existe alguma explicação para esse problema da inversão da data? Ou seja uma vez inverte e na outra não!
Avatar do usuário
Por LeoHenrique
Posts Avatar
#45731
Bom dia !!

Excelente !!! Perfeito ! Obrigado JCabral e Osvaldomp. Funcionou perfeitamente.

Vou deixar o tópico aberto, se não for pedir muito, para você Osvaldomp, me explicar o por que da alteração... tentei entender, mas não chego a uma explicação.

Muito obrigado novamente.

Leandro Henrique
Por osvaldomp
#45746
JCabral escreveu:Existe alguma explicação para esse problema da inversão da data? Ou seja uma vez inverte e na outra não!
A MS conseguiu lidar, quase sem bugs, com datas em planilhas , já no VBA, há problemas.
O pouco que sei é que o VBA foi ensinado (configurado) para ler as datas sempre no formato americano "mm/dd/aa". A exceção é se o o número correspondente ao mês for maior do que 12, nesse caso, ele foi ensinado para ler como "dd/mm/aa".
Com base nesses ensinamentos o VBA ficou meio atrapalhado ao lidar com datas nas versões do Office que adotam um formato diferente do americano.

Veja nos exemplos abaixo os resultados dessa trapalhada.

Primeiro mande o VBA inserir a data 05/julho/19 , assim ~~~> 05/07/19, aí ele entende julho/05/19 e coloca na célula 07/05/19.

Então eu digo pra ele: "não é isso, eu quero inserir como 05/julho/19, assim ~~~> Format("05/07/19", "dd/mm/yyyy")" ~~~> aí ele reage ~~~> ok, entendido ~~~> e insere 07/05/19.

Aí eu vou contra a lógica e digo que quero assim ~~~> Format("05/07/19", "mm/dd/yyyy") ~~~> ah, agora entendi, lá vai ~~~> 05/07/19. Ou seja, eu digo pra ele fazer errado e aí ele decide fazer certo.

'[D5] = "05/07/19" 'resulta ~~~> 07/05/19
'[D5] = Format("05/07/19", "dd/mm/yyyy") 'resulta ~~~> 07/05/19
'[D5] = Format("05/07/19", "mm/dd/yyyy") 'resulta~~~> 05/07/19
'[D5] = DateValue("05/07/19") 'resulta~~~> 05/07/19
'[D5] = Format(DateValue("05/07/19"), "dd/mm/yy") 'resulta~~~> 07/05/19
'[D5] = Format(DateValue("05/07/19"), "mm/dd/yy") 'resulta~~~> 05/07/19

LeoHenrique escreveu: ... me explicar o por que da alteração... Leandro Henrique
A qual alteração você se refere ?
Por osvaldomp
#45748
Excluída por duplicidade.
Editado pela última vez por osvaldomp em 19 Jul 2019 às 22:37, em um total de 2 vezes.
Por osvaldomp
#45749
JCabral escreveu:Existe alguma explicação para esse problema da inversão da data? Ou seja uma vez inverte e na outra não!
A MS conseguiu lidar com datas em planilhas quase sem bugs, já no VB há problemas.
O pouco que sei é que o VBA foi ensinado (configurado) para ler as datas sempre no formato americano "mm/dd/aa". A exceção é se o o número correspondente ao mês for maior do que 12, nesse caso, ele foi ensinado para ler como "dd/mm/aa".
Com base nesses ensinamentos o VBA ficou meio atrapalhado ao lidar com datas nas versões do Office que adotam um formato diferente do americano.

Veja nos exemplos abaixo os resultados dessa trapalhada.

Primeiro mande o VBA inserir a data 05/julho/19 , assim ~~~> 05/07/19, aí ele entende julho/05/19 e coloca na célula 07/05/19.

Então eu digo pra ele: "não é isso, eu quero inserir como 05/julho/19, assim ~~~> Format("05/07/19", "dd/mm/yyyy")" ~~~> aí ele reage ~~~> ok, entendido ~~~> e insere 07/05/19.

Aí eu vou contra a lógica e digo que quero assim ~~~> Format("05/07/19", "mm/dd/yyyy") ~~~> ah, agora entendi, lá vai ~~~> 05/07/19. Ou seja, eu digo pra ele fazer errado e aí ele decide fazer certo.

'[D5] = "05/07/19" 'resulta ~~~> 07/05/19
'[D5] = Format("05/07/19", "dd/mm/yyyy") 'resulta ~~~> 07/05/19
'[D5] = Format("05/07/19", "mm/dd/yyyy") 'resulta~~~> 05/07/19
'[D5] = DateValue("05/07/19") 'resulta~~~> 05/07/19
'[D5] = Format(DateValue("05/07/19"), "dd/mm/yy") 'resulta~~~> 07/05/19
'[D5] = Format(DateValue("05/07/19"), "mm/dd/yy") 'resulta~~~> 05/07/19


"Ou seja uma vez inverte e na outra não!" ~~~> provavelmente porque ao inserir a primeira data na célula vazia ela é inserida como data real, aí o VBA inverte, já ao inserir a segunda data na célula ela é inserida como texto, e nesse caso o VBA não inverte.

LeoHenrique escreveu: ... me explicar o por que da alteração... Leandro Henrique
A qual alteração você se refere ?
Editado pela última vez por osvaldomp em 19 Jul 2019 às 22:41, em um total de 2 vezes.
Avatar do usuário
Por LeoHenrique
Posts Avatar
#45750
Boa tarde e obrigado pelo retorno Osvaldomp !

A parte que me refiro, são as alterações acima que você sugeriu para que o código funcionasse. Porém ainda estou tentando entender o que cada linha faz. Já me enviou alguns códigos maiores, se não for pedir muito, se puder comentar o que cada linha faz e o por que "pode ser resumido" entenderei os outros que já me enviou tb.


If [X7] <> "" Then Range("X7:X" & Cells(Rows.Count, 22).End(3).Row).Value = "" ( Entendo que se X7 for diferente de "" então ... ? )
For Each ref In Range("B7:B" & Cells(Rows.Count, 2).End(3).Row) (Para cada linha ref ...... ? )
Set dat = Sheets("Faturados").[G:G].Find(ref.Value) (O que set faz ? / seleciona aba "faturados" ..... ? )
If Not dat Is Nothing Then (Se não tiver nada então ... isso ? )
refAdd = dat.Address (Essa linha faz uma comparação, correto ? )
Do (Faça )
ref.Offset(, 22) = IIf(ref.Offset(, 22).Value = "", _ (Sei que o offset é deslocamento, mas aqi é a coluna ?)
dat.Offset(, 19).Value, ref.Offset(, 20).Value & Chr(10) & dat.Offset(, 19).Value) (Não entndi essa .... )
Set dat = Sheets("Faturados").[G:G].FindNext(After:=dat) (Set dat "o que faz?" / Seleciona aba "faturados) e ....?)
Loop While dat.Address <> refAdd (Faz loop enquanto _____________ ? )
End If
Next ref
End Sub

Se puder detalhar, agradeço imensamente.
Muito obrigado Osvaldomp !!
Por osvaldomp
#45823
LeoHenrique escreveu:If [X7] <> "" Then Range("X7:X" & Cells(Rows.Count, 22).End(3).Row).Value = "" ( Entendo que se X7 for diferente de "" então ... ? )
Esse comando limpa de X7 para baixo, porém se X7 estiver vazia o comando irá limpar de X7 para cima, o que é indesejável, então coloquei uma condição para limpar somente se X7 não estiver vazia.


For Each ref In Range("B7:B" & Cells(Rows.Count, 2).End(3).Row) (Para cada linha ref ...... ? )
No código a variável "ref" está declarada como "Range" então o comando For Each ref irá efetuar um Loop pelas células do intervalo B7 até a última linha com conteúdo em B.

Set dat = Sheets("Faturados").[G:G].Find(ref.Value) (O que set faz ? / seleciona aba "faturados" ..... ? )
Esse comando irá procurar uma duplicação da variável "ref" na coluna G da planilha "Faturados" e irá atribuir o resultado da procura à variável "dat".


If Not dat Is Nothing Then (Se não tiver nada então ... isso ? )
Traduzindo: se não "dat" é nada.
Raciocínio Lógico ~~~> não de não é sim, então se não "dat" é nada significa que sim, a duplicação foi encontrada.


refAdd = dat.Address (Essa linha faz uma comparação, correto ? )
Esse comando atribui à variável "refAdd" o endereço da célula em que foi encontrada a primeira ocorrência de "dat". Esse endereço será critério para encerrar o Loop, veja mais abaixo.

Do (Faça )
Isso, inicia um Loop

ref.Offset(, 22) = IIf(ref.Offset(, 22).Value = "", _ (Sei que o offset é deslocamento, mas aqi é a coluna ?)
Sim, 22 colunas à direita da referência. A sintaxe é Offset(linhas, colunas)

dat.Offset(, 19).Value, ref.Offset(, 22).Value & Chr(10) & dat.Offset(, 19).Value) (Não entndi essa .... )
Esse comando é continuação do anterior. Insere na 22a. coluna à direita de "ref" cópia do valor de dat.Offset(, 19)

Set dat = Sheets("Faturados").[G:G].FindNext(After:=dat) (Set dat "o que faz?" / Seleciona aba "faturados) e ....?)
É continuação do Set dat anterior via Find ... FindNext, utilizado para procurar múltiplas ocorrências via Loop.
Vale a pena você pesquisar sobre esse recurso. Tenho visto códigos nos fóruns que o cidadão faz uma busca de célula por célula para retornar múltiplas ocorrências. Imagine que há 5 mil linhas na coluna e 3 ocorrências buscadas que estão nas linhas 80, 150 e 250. A busca da linha 251 até a linha 5 mil será inútil. Nesses casos o FindNext é mais eficiente.


Loop While dat.Address <> refAdd (Faz loop enquanto _____________ ? )
Faz o Loop até retornar à célula da primeira ocorrência de "dat".
dicas:
1. para acessar a ajuda de qualquer comando coloque o cursor sobre ele e aperte F1.
2. para acompanhar a ação de cada comando sobre a planilha, ajuste o tamanho e a posição da tela do editor VBA de modo que você consiga visualizar a área relevante da planilha e execute o código via F8.
Avatar do usuário
Por LeoHenrique
Posts Avatar
#45882
Muito obrigado Osvaldo !

Vou estudar e testar esses códigos... Os cursos que estou fazendo "pago" e "não pago" pela internet, nunca vi a junção desses códigos da forma que você usa. Se souber onde encontro esse material para estudar, poderia me informar por favor ?


Muito obrigado novamente pelas informações !
Abraço
Leandro Henrique = leandro.manhani@gmail.com
long long title how many chars? lets see 123 ok more? yes 60

We have created lots of YouTube videos just so you can achieve [...]

Another post test yes yes yes or no, maybe ni? :-/

The best flat phpBB theme around. Period. Fine craftmanship and [...]

Do you need a super MOD? Well here it is. chew on this

All you need is right here. Content tag, SEO, listing, Pizza and spaghetti [...]

Lasagna on me this time ok? I got plenty of cash

this should be fantastic. but what about links,images, bbcodes etc etc? [...]

Estamos migrando para uma comunidade no Discord