Página 1 de 1

REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 25 Mar 2022 às 11:24
por AMORIM123
No procedimento abaixo tenho um array que armazena a área com dados de uma tabela na planilha x (ShtNFe); também tenho um dicionário declarado no topo do módulo pra ficar público nesse módulo; esse dicionário contém como item: 'COD_PROD', 'DESCRICAO', 'NCM' e 'CLASSIFICACAO' e como chave: 'COD_PROD'. Faço uma comparação entre array vs dicionário para obter a CLASSIFICACAO da tecla no dicionario e repassar para o registro no array, ao final todos os registros no array estarão devidamente classificados; Para repassar a classificação para a tabela o que me importa é o último campo, porém como subi toda a tabela para memória do array precisei fazer um tratamento disso, criando um novo dicionário apenas pra esse procedimento para na sequência descarregar em novo array e ao final do loop For repassar o conteúdo inteiro, de uma só vez para coluna da tabela. Bem até aqui tudo massa!
Código: Selecionar todos
Public Sub Apply_Rating()

Dim arrShtNFe     As Variant
Dim endCell       As Long
Dim i             As Long
Dim arrDisc       As Variant
Dim Dict          As New Scripting.Dictionary
Dim arrDef        As Variant
Dim rng           As Range
Dim tblDefault    As ListObject
Dim efinal        As Long

Set tblDefault = ShtDefault.ListObjects("Default")

With ShtNFe

    ShtNFe.Activate
    'METODO RANGE FALHA QUANDO A PLANILHA 'NFe' NÃO ESTÁ ATIVA
    endCell = .Cells(.rows.count, 1).End(xlUp).row
    arrShtNFe = .Range(.Cells(2, 1), Cells(endCell, 52))
    
    For i = LBound(arrShtNFe) To UBound(arrShtNFe)
                                                              'arrShtNFe(i, 52) = DictProcessing(CStr(arrShtNFe(i, 14)))(4)
        If DictProcessing.Exists(CStr(arrShtNFe(i, 14))) Then
            arrShtNFe(i, 52) = DictProcessing(CStr(arrShtNFe(i, 14)))(4)
            Dict(i) = arrShtNFe(i, 52)
        End If
        
        If i >= UBound(arrShtNFe) Then
            arrDisc = Dict.Items
            ShtNFe.ListObjects("NFe").ListColumns(52).DataBodyRange.value = Application.transpose(arrDisc)
            Dict.RemoveAll
            endCell = 0
        End If
    Next i

End With


    ShtDefault.Activate

    arrDef = DictNewItemDefault.Items
    tblDefault.ListRows.Add alwaysinsert:=True
    efinal = tblDefault.DataBodyRange.End(xlDown).Offset(1).row
        
    Set rng = tblDefault.Range.Offset(tblDefault.Range.rows.count).rows.Resize(DictProcessing.count)
       tblDefault.DataBodyRange(efinal, 4).value = arrDef
'       rng.ListColumns(2).DataBodyRange.value = Application.transpose(arrDef, 1)
'       rng.ListColumns(3).DataBodyRange.value = Application.transpose(arrDef, 2)
'       rng.ListColumns(4).DataBodyRange.value = Application.transpose(arrDef, 3)

    
End Sub
Agora preciso fazer algo parecido, no sentido de descarregar um array em outra tabela (tblDefault) , sem loopar, todo o conteúdo do array a partir da linha inserida na tabela após a última linha com dados.

Espero ter ser sucinto nos objetivos; sei que é um pouco complicado sugerir algo sem debugar o código, porém na real o problema se resumo a "Redimensionar Tabela apartir da Última linha com dados" para receber conteúdo de array.

Desde já agradeço a interação.

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 25 Mar 2022 às 20:17
por PHSabater
Tente definir um range com mesma dimensão do array.

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 25 Mar 2022 às 20:37
por AMORIM123
@PHSabater, Essa é lógica, porém não consigo executá-la com sucesso.
Código: Selecionar todos
'AQUI FAÇO A INSERCAO DE UMA LINHA SEM DADOS NA TABELA P/
'A PARTIR DELA REDIMENSIONA-LA DO MESMO TAMANHO DO ARRAY OU DICIONARIO
 tblDefault.ListRows.Add alwaysinsert:=True
 
 'AQUI PEGO A POSICAO DESSA LINHA INSERIDA P/ USAR POSTERIORMENTE
 efinal = tblDefault.DataBodyRange.End(xlDown).Offset(1).row

'AQUI DEFINI UM VARIÁVEL OBJETO DO TIPO RANGE PARA REDIMENSIONAR A TABELA EFETIVAMENTE
'PARA PODER PASSAR VALORES NO SEU INTERVALO
 Set rng = tblDefault.Range.Offset(tblDefault.Range.rows.count).rows.Resize(DictProcessing.count)
 
 'NA LINHA ABAIXO ONDE HÁ JÁ TESTEI A SUBSTITUIR POR rng 
 'PARA DESCARREGAR OS DADOS MAIS NÃO DEU ROCK
 tblDefault.DataBodyRange(efinal, 4).value = arrDef
Anexei um exemplo se tiver como demonstrar de forma prática, então lhe sou grato, talvez eu já esteja de cabeça pesada por tentar resolver esse problema e não conseguir..rsrs

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 25 Mar 2022 às 21:15
por PHSabater
Redimensione conforme código abaixo para descarregar o array.
Código: Selecionar todos
Plan1.Range("B13").Resize(vLinhas, vColunas) = myarray
Onde vLinhas, vColunas é referente ao tamanho do seu array.

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 26 Mar 2022 às 11:31
por AMORIM123
@PHSabater

Imagem

https://1drv.ms/u/s!Aj-bsGYbi-JEgY1MiGk ... Q?e=7WV7Hx

Na imagem acima tentei algo no mesmo sentido, porém usando a propriedade .count do dicionário no argumento RowSize; observa que o meu array está devidamente povoado, o código é executado plenamente, porém o esperado não ocorre.

DETALHE: Preciso que o objeto que receba os dados do array seja uma tabela, pois essa tabela será manipulada no power pivot na sequência.

Em anexo o projeto completo. O módulo que contém o código é o Módulo2, talvez vc tenha que habilitar a biblioteca Microsoft Scripting Runtime

ANEXO
FrontCalc V.1.13.5 - REVIEW.xlsm

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 26 Mar 2022 às 15:24
por PHSabater
@AMORIM123, não está dando certo porque esse array que está tentando inserir está chegando sem informações.
Código: Selecionar todos
 For Each t In arrDef
        MsgBox t
    Next
Faça o teste com esse código, ou qualquer outro que extraia informação do array.

Pode ser até
Código: Selecionar todos
msgbox arrdef(1,1) 
Código: Selecionar todos
arrDef = DictNewItemDefault.Items
Não depurei seu código completo, mas tem que verificar se DictNewItemDefault está te entregando os itens do listbox.

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 26 Mar 2022 às 15:44
por AMORIM123
@PHSabater, Ele chega sem a info se a última coluna da tabela NFe estiver preenchida; ao apagar os dados dessa coluna o dicionario é povoado e na sequência o array tbm.

imagem: https://1drv.ms/u/s!Aj-bsGYbi-JEgY1M3qB ... Q?e=s6y3L8

Imagem

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 26 Mar 2022 às 21:40
por PHSabater
@AMORIM123, Scripting é novo pra mim.... nunca utilizei...

Mas fazendo um for each no Scripting que carrega o seu array, ele só tá vindo os códigos dos produtos.

Qual o objetivo da sua planilha? Classificar os produtos (registros únicos)?

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 28 Mar 2022 às 14:44
por AMORIM123
Opâ saudossímo @PHSabater

O objeto dicionário disponível pela biblioteca MS Scripinting Runtime só possuí dois itens (Tecla e Item); a Tecla é aquilo que identifica o item no dicionário e o item pode ser qualquer coisa, inclusive um array que é como utilizo no meu código. Quando vc faz o for each e põe pra imprimir ele vai mostrar apenas a Tecla, que no caso é o código do produto, porém se vc utilizar o método .Items no dicionário e passar o conteúdo dos items para um array, então ele descarrega todo o contéudo de itens no array. Caso queira aprender mais sobre dicionários veja os links, são ótimos artigos, porém estão em inglês

https://www.snb-vba.eu/VBA_Dictionary_en.html#L_0
https://excelmacromastery.com/vba-dictionary/

OBJETIVO: Tenho um dicionário que recebe informações de um listview que obtém uma classificação de alguns produtos do usuário, esses itens são considerados itens novos e devem ser armazenado em uma tabela base, de uma só vez (uma das vantagens de se utilizar array), na sequência esses dados no array devem ser registrados nessa tabela base; é necessário que seja em uma tabela pois a utilizarei para subir dados p/ o power pivot.

Simplicando o problema trata-se de redimensionar uma tabela com o tamanho em linhas que tem um array e a quantidade de colunas sempre igual a 4 .

Para você conseguir depurar o código e ir entendo o que ocorre, vc habilita essa biblioteca 'Microsoft Scripting Runtime', depura o módulo2, sempre antes de depurar verifica se a planilha NFe, tem a tabela NFe e a ÚLTIMA coluna sem dados (NÃO EXCLUÍ, SÓ LIMPA); o procedimento onde tento resolver o problema é o Apply_Rating(), põe um ponto de interrupção lá e aperta F5; será exibido um userform simples, vc classifica todos os itens de uma só vez, o listbox é multiselect, quando vc chegar no Apply_Rating() vc vai vê que o código executa tranquilamente, porém a tabela não recebe os dados como esperado.

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 31 Mar 2022 às 19:24
por PHSabater
@AMORIM123, Boa noite.

Fiquei ausente por esses dias... já solucionou?

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 02 Abr 2022 às 21:47
por AMORIM123
@PHSabater , Muito obrigado por interagir, graças à Deusa Mnemosine e às ferramentas de depuração consegui vê onde estava meu problema...rsrsrs

Na verdade o problema não estava em redimensionar a tabela pra receber os dados do array, mas sim em como o array estava sendo populado, como vc havia notado anteriormente; Em outros procedimentos no mesmo módulo eu tinha um Dicionário que recebia em cada tecla um array que na verdade era vetor com 4 posições; ao descarregar esse dicionário em um novo array, após os processamentos que queria realizar, eu esperava que ele tivesse o compartamento de uma matriz🤦🏽‍♂️, porém como os dados de origem eram um vetor o propósito nunca seria alcançado, né (rsrsrs). 

Revi o código escrito e consegui manipular para que o array se compartasse como uma matriz, então deu rock!

Mais uma vez muito obrigado!!

Re: REDIMENSIONAR TABELA (PARA RECEBER ARRAY) A PARTIR DA ÚLTIMA LINHA COM DADOS

Enviado: 07 Abr 2022 às 19:00
por PHSabater
Maravilha.
Eu fiz a solução também sem o Dicionário, acabei não postando porque tive uns imprevistos... agora que está normalizando por aqui.
Abraço.