Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
SuperBond

Mostrar valores contidos em células

Recommended Posts

SuperBond    3

Tô começando agora em VBA, usando Excel 2010 e gostaria de fazer uma coisa muito simples: mostrar numa box o valor contido em duas células, A1 e A2, que estão na planilha 9.

 

post-565727-0-31020800-1420117613.png

 

O código que estou tentando é:

Sub ShowValue()Contents = Worksheets("Plan9").range("A1:A2").ValueMsgBox ContentsEnd Sub

o que aparece é um erro de tipos incompatíveis. Se eu escrever range("A1"), funciona e mostra o valor 6, mas range("A1:A2") não. A tela do erro:

 

post-565727-0-48151700-1420117620.png

Editado por SuperBond

Compartilhar este post


Link para o post
Compartilhar em outros sites
osvaldomp    673

Se a Plan9 for a planilha ativa:

Sub MostraConteúdo1() MsgBox "A1 =  " & [A1] & vbLf & "A2 =  " & [A2]End Sub

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
SuperBond    3
  • Autor do tópico
  • Ok, e se eu quiser que os valores das celulas estejam num array? Fiz um pequeno código que mostraria os valores mediante uma condição, só que não roda.

    Sub MostraConteúdoCel()Dim Celu(1 To 5) As Integer    If [B2] = 3 Then       MsgBox Celu    Else       MsgBox " B2 não é igual a 3"    End IfEnd Sub

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    minoso    196

    No seu pequeno código condicional a variável Celu não recebe valor algum para ser impressa no MsgBox.

    Você teria que carregar sua array e, então, exibi-la com a concatenação sugerida pelo @osvaldomp

    Já tentou?

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

    @SuperBond

     

    Preencha o intervalo "A1:A5" da planilha ativa e rode o código.

    Sub CélulasParaMatriz()  Dim MatrizX(), i As Long    MatrizX = Range("A1:A5").Value      For i = 1 To 5        MsgBox MatrizX(i, 1)      Next iEnd Sub

    Veja no link abaixo um curso sobre macros.

     

    aulas de macros/vba-Bertolo

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • @osvaldomp

     

    Legal desse jeito, mas o que eu pretendia era exibir os valores de uma vez só, tentei modificar o código que você fez, mas não funcionou.

    Obrigado pelo link, até salvei aqui. Eu tenho um livro até bom de VBA, do John Walkenbach, mas não encontro um exemplo especifico de como exibir uma faixa de valores de uma unica vez, tentei usar cells, mas não funcionou.    

    Editado por SuperBond

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

    Sub CélulasParaMatriz()

      Dim MatrizX(), i As Long, AA As String

        MatrizX = Range("A1:A5").Value 'carrega na matriz os valores do intervalo

        [E1].Resize(5).Value = MatrizX 'insere em outro intervalo os elementos da matriz

          For i = 1 To 5

            AA = AA & MatrizX(i, 1) & vbLf 'carrega na variável "AA" todos os elementos da matriz

          Next i

       MsgBox AA 'exibe a variável "AA"

    End Sub

    • Curtir 2

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • OK, eu não estava entendendo como carregar a variavel, agora sim. Obrigado.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • Opa, reabri o tópico porque tenho uma outra necessidade. Tenho a seguinte tabela:

     

    post-565727-0-70671700-1420415930_thumb.

     

    Quero criar uma macro que verifique se alguma soma de preços das colunas DEZ e JAN é igual a algum valor de imposto bimestral 1(Imp1) E se alguma soma de preços das colunas JAN e FEV é igual a algum imposto bimestral 2(Imp2). 

    Se DEZ + JAN for igual ao imposto bimestral 1(Imp1) E se JAN + FEV for igual a algum valor de imposto bimestral 2(Imp2), deve escrever na caixa a sequencia dos três preços que satisfazem essas condições.

     

    Só que o principal é que não devem ser misturados os preços das linhas, por exemplo, não pode usar R$1+ R$3, ambos da linha 3, + R$5, da linha 4. Essa combinação, a princípio, satisfaz as condições, Imp1 = R$4 e Imp2 = R$8, só que usa valores das duas linhas.

    O código que fiz faz o que disse acima, que não é o desejado.

    Sub TestImp()  Dim Prec1(), Prec2(), Prec3(), i As Long, j As Long, k As Long, l As Long, m As Long  Dim PreFin As String    Imp1 = range("E3:E5").Value    Imp2 = range("F3:F5").Value    Prec1 = range("A3:A7").Value 'carrega na matriz os valores do intervalo    Prec2 = range("B3:B7").Value 'carrega na matriz os valores do intervalo    Prec3 = range("C3:C7").Value 'carrega na matriz os valores do intervalo     For i = 1 To 2        For j = 1 To 2           For k = 1 To 2              For l = 1 To 3                 For m = 1 To 3             If Prec1(i, 1) + Prec2(j, 1) = Imp1(l, 1) And Prec2(j, 1) + Prec3(k, 1) = Imp2(m, 1) Then                 PreFin = PreFin & Prec1(i, 1) & Prec2(j, 1) & Prec3(k, 1) & vbLf             End If                 Next m              Next l           Next k        Next j     Next i         MsgBox PreFinEnd Sub

    O correto seria somente a saída 133, que junta os preços somente da linha 3. A saida 135 já não serve, o R$5 é da linha 4.

    Teria que criar uma rotina que analise em linha, chegou ao ultimo preço da linha, passa para a proxima linha e assim por diante. E isso para uma grande quantidade de preços ou linhas. 

    Há uma função em VBA que faça esta analise?

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

    Opa, reabri o tópico porque tenho uma outra necessidade.

    Claro, pois não!

     

    E isso para uma grande quantidade de preços ou linhas. 

    Há uma função em VBA que faça esta analise?

    Para efeitos de testar algum código antes de ser postá-lo aqui, alguém que esteja disposto a lhe ajudar teria que reproduzir a sua planilha, preenchendo todas as células manualmente. O que não é razoável.

    Sugiro que você disponibilize uma amostra do seu arquivo, com cerca de 5 registros como exemplos, coloque na própria planilha os resultados esperados para cada um dos registros.

     

    Veja se entendi corretamente:

     

    registro da linha 3

        Soma1 = A3 + B3 = 4  > >  buscar essa Soma1 em "E"  > >  encontrada em E4

        Soma2 = B3 + C3 = 6  > >  buscar essa Soma2 em "F"  > >  encontrada em F3

        este registro atende, então > >  valores a exibir na Caixa de Mensagem: A3 & B3 & C3

    registro da linha 4   

        Soma1 = A4 + B4 = 8  > >  buscar essa Soma1 em "E"  > > não encontrada

        este registro não atende, então > > não vai para a Caixa de Mensagem

     

     

    Se não for isso descreva novamente direto na planilha a ser disponibilizada.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • É isso. Só corrigindo que na imagem que colei lá acima  Soma1 = A3 + B3 = 4  a soma correspondente Soma1 está em E5 e não em E4. Mas é essa a intenção. Uma planilha com alguns valores e uma explicação mais detalhada tá no anexo. 

     

    Pasta1.xlsx

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

    Sub VerificaSomaPreços()

     Dim LR As Long, k As Long, AA As String

      LR = Cells(Rows.Count, 1).End(xlUp).Row

       For k = 3 To LR

        If Application.CountIf([E:E], (Cells(k, 1) + Cells(k, 2))) > 0 And _

          Application.CountIf([F:F], (Cells(k, 2) + Cells(k, 3))) > 0 Then

          AA = AA & Cells(k, 1) & Cells(k, 2) & Cells(k, 3) & vbLf

         End If

       Next k

      MsgBox AA

    End Sub

    • Curtir 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • Por favor, pode me explicar como funciona o código? O coutif tem um intervalo e um critério, que seriam E:E e F:F e o criterio seriam (Cells(k, 1) + Cells(k, 2)... Mas LR = Cells(Rows.Count, 1).End(xlUp).Row "  como funciona?

     

    Como aloco os dados nas tabelas, os preços e as somas?

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

    Isso, o 'CountIf' equivale à função de planilha 'Cont.Se'.

     

    LR = Cells(Rows.Count, 1).End(xlUp).Row

     

    LR > variável do tipo Long que vai assumir o número da última linha da sua tabela

     

    Cells(Rows.Count, 1) > a sintaxe deste comando é Cells(linha, coluna),

    o comando Rows.Count retorna o numero da última linha da planilha, no caso do XL 2003 retorna 64 mil e mais um pouco que não me lembro e a partir do XL 2007 retorna 1048576 e 1 corresponde à coluna "A", então Cells(1048576,1) é a última linha da planilha, coluna "A".

    o comando End(xlUP) equivale a apertar a tecla End e em seguida apertar a tecla setinha pra cima, então a seleção que estava em "A1048576"vai parar na última célula da tabela, na coluna "A", e o Row ao final captura o número dessa linha

    essa variável serve para informar ao loop For...Next o limite superior do loop, sendo o inferior, 3, o número da primeira linha da tabela

     

    obs. alguns utilizam o comando de cima para baixo com o objetivo de capturar a última linha da tabela, assim: Cells(1,1).End(xlDown) ou Range("A1").End(xlDown), no entando este método pode falhar se houver alguma célula vazia na tabela, na coluna "A", erro que não ocorre com o método de baixo para cima

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • Se eu rodar seu código do jeito que está não aparece nada na box, então fiz umas adaptações para minha planilha, dentro do que entendi, e resultou em erro. O que falta corrigir? A tabela que estou usando tá na imagem:

     

    post-565727-0-31723000-1420512865.png

    Sub VerificaSomaPreços() Dim LR As Long, k As Long, AA As String Prec1 = range(Cells(1, 1)) Prec2 = range(Cells(2, 1)) Prec3 = range(Cells(3, 1))  LR = Cells(Rows.Count, 1).End(xlUp).Row   For k = 3 To LR     If Application.CountIf([E:E], (Prec1(k, 1) + Prec2(k, 1))) And _      Application.CountIf([F:F], (Prec2(k, 1) + Prec3(k, 1))) Then      AA = AA & Prec1(k, 1) & Prec2(k, 1) & Prec3(k, 1) & vbLf     End If   Next k     MsgBox AAEnd Sub

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

     

    Se eu rodar seu código do jeito que está não aparece nada na box,

     

    Ao rodar o código que postei no post #12 no arquivo que você disponibilizou no post #11 o resultado que obtenho aqui na Caixa de Mensagem é:

    791

    885

    337

    Se você não está conseguindo esse resultado algo está errado/diferente aí.

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • Eu estava usando outra planilha, aí não funcionava. É funciona mesmo, obrigado. Agora estou estudando cada linha desse código. 

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • @osvaldomp

     

    Tudo bem? Se você pudesse me dar uma luz nessa questão ficaria grato. Numa matriz de 3x4 há 12 letras diferentes, 4 por linha. Preciso combinar as 4 letras de cada linha, sem repetição e sem misturar com outras linhas, e mostrar as 72 combinações(dá 24 por linha) numa célula. 

    Criar um código para ler em linha já fizemos, mas como combinar o conteudo das celulas? Se eu fosse fazer uma rotina pra cada uma das 24 situações ficaria um código gigante. Deve haver uma saida melhor.

     

    Eu sei mais ou menos fazer isso em Pascal, onde eu vou alocando os valores em variáveis temporárias, atribuindo e esvaziando nessas variaveis a cada combinação feita, mas em VBA estou sem saber. A figura dá uma explicação a mais. Precisava de uma ideia por onde começar.

     

    post-565727-0-66811700-1420780820_thumb.

     

     

     

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

    Seguem 2 opções. Diferem quanto ao intervalo onde lançam o resultado. Para ambas a tabela com as letras a serem permutadas deve estar em "A2:D4", conforme a sua figura. A opção1 coloca o resultado em "F6" e a opção2 coloca em "F2:AC4". Cada opção é formada por 2 códigos. Sugiro que, para testar, coloque uma opção em um módulo e a outra em outro módulo.

     

    os códigos a seguir foram adaptados a partir da solução existente neste site

     

     

    opção1

    Option ExplicitDim AA As String'// matriz com as letras em "A2:D4" e resultado em uma única célula "F6"Sub GetStringF6()    Dim InString As String, m As Long        For m = 2 To 4         InString = Cells(m, 1) & Cells(m, 2) & Cells(m, 3) & Cells(m, 4)         Call GetPermutationF6("", InString)        Next m     [F6] = AA: AA = ""     Columns(6).ColumnWidth = 61     With [F6]        .HorizontalAlignment = xlGeneral        .VerticalAlignment = xlTop        .WrapText = True     End With     Rows(6).EntireRow.AutoFitEnd SubSub GetPermutationF6(x As String, y As String)'   The source of this algorithm is unknown    Dim i As Integer, j As Integer ', AA As String    j = Len(y)    If j < 2 Then        AA = AA & " " & x & y        Debug.Print AA & vbLf    Else        For i = 1 To j            Call GetPermutationF6(x + Mid(y, i, 1), _            Left(y, i - 1) + Right(y, j - i))        Next    End IfEnd Sub

    >>>>>>>>>>>>>

    >>>>>>>>>>>>>

     

    opção2

    Option ExplicitDim CurrentRow As LongDim CurrentCol As Long'// matriz com as letras em "A2:D4" e resultado em "F2:AC4"Sub GetStringF2AC4()    Dim InString As String, m As Long        ActiveSheet.Range("F2:AC4").ClearContents        CurrentRow = 1        For m = 2 To 4         CurrentCol = 5         InString = Cells(m, 1) & Cells(m, 2) & Cells(m, 3) & Cells(m, 4)         CurrentRow = CurrentRow + 1: CurrentCol = CurrentCol + 1         Call GetPermutationF2AC4("", InString)        Next mEnd SubSub GetPermutationF2AC4(x As String, y As String)'   The source of this algorithm is unknown    Dim i As Integer, j As Integer    j = Len(y)    If j < 2 Then        Cells(CurrentRow, CurrentCol) = x & y        CurrentCol = CurrentCol + 1    Else        For i = 1 To j            Call GetPermutationF2AC4(x + Mid(y, i, 1), _            Left(y, i - 1) + Right(y, j - i))        Next    End IfEnd Sub

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  •  @osvaldomp  

     

     

    Fala Osvaldomp! Obrigado por estes códigos. Arranjei uma solução mais simples, mas eficiente e que estava bem na minha cara o tempo todo :muro:  

    Sub GetCombinacoes()Dim i As Long, j As Long, k As Long, m As LongFor i = 1 To 4   For j = 1 To 4      For m = 1 To 4         For n = 1 To 4     A = Cells(1, i)     B = Cells(1, j)     C = Cells(1, m)     D = Cells(1, n)     If i <> j And i <> m And i <> n And j <> m And j <> n And m <> n Then        AA = AA & A & B & C & D & vbLf     End If         Next n      Next m   Next jNext i   MsgBox AAEnd Sub

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

    Eu já utilizei um código parecido. Seguem alguns comentários sobre ele.

    O resultado que esse código apresenta não é exatamente o que você pediu. :confused:
    Ele permuta somente 4 letras, colocadas em "A1:D1", por exemplo, "ABCD", diferentemente do que você pediu que foi permutar 3 grupos de 4 letras cada, separadamente . E as permutações de "EFGH" e de "IJKL"? ^_^ Esse código não faz.

    Incremente o seu código para permutar mais 2 grupos de 4 letras cada, conforme foi o seu pedido e coloque-o aqui! :rolleyes:

    Um outro ponto é que o seu código é tipo "amarrado" (hard coded) por causa destes comandos:
     If i <> j And i <> m And i <> N And j <> m And j <> N And m <> N Then
       AA = AA & A & B & c & D & vbLf
     End If

    Esse arranjo, em conjunto que os 4 "loops" For...Next, serve permutar somente 4 elementos, ex. "ABCD". Para permutar quantidades diferentes, ex. "ABCDEF", será preciso adaptá-lo. De forma análoga, para permutar 3 elementos, ex. "ABC", também será preciso adaptá-lo. ^_^

    Essas limitações não existem no código que postei, que foi bolado por um gênio,  :tantan::aplausos: e o "pulo do gato" são os comandos abaixo, coração do código, que conseguem permutar qualquer quantidade de elementos.
    For i = 1 To j
        Call GetPermutationF2AC4(x + Mid(y, i, 1), _
        Left(y, i - 1) + Right(y, j - i))
     Next

     

    No código que postei a parte "hard coded" é a que captura quais os elementos a serem permutados. Isto porque você definiu a quantidade deles e onde eles deveriam ficar, mas pode ser alterado uma única vez para capturar e permutar qualquer quantidade de elementos, e possíveis variações, sem a necessidade de mexer no código, ou seja, é uma estrutura que visa desempenho flexível. :jump:;)

     

    Editado por osvaldomp

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • Verdade, é um código totalmente versátil.

    Agora em relação ao meu código, faltou mesmo combinar as letras das outras linhas. Então no lugar de "1" nas cells, coloquei um indice "o" e fiz um loop, onde o limite superior é dado pelo bom e velho

     

    LR = Cells(Rows.Count, 1).End(xlUp).Row

     

    para que ele combine n grupos de n linhas.

    Sub GetProdutos()Dim i As Long, j As Long, k As Long, m As Long, n As Long, o As Long, LR As LongLR = Cells(Rows.Count, 1).End(xlUp).RowFor o = 1 To LR   For i = 1 To 4...      

    Nesse meu código, como faço com que cada combinação ocupe uma célula? Assim:

    post-565727-0-45010500-1421197097.png

     

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

    Nesse meu código, como faço com que cada combinação ocupe uma célula? Assim:

    attachicon.gifEM CADA CEL.PNG

    Option ExplicitSub GetCombinacoes()Dim i As Long, j As Long, k As Long, m As Long, N As LongDim A As String, B As String, C As String, D As StringDim AA As String, x As LongFor i = 1 To 4   For j = 1 To 4      For m = 1 To 4         For N = 1 To 4     A = Cells(1, i)     B = Cells(1, j)     C = Cells(1, m)     D = Cells(1, N)     If i <> j And i <> m And i <> N And j <> m And j <> N And m <> N Then        'AA = AA & A & B & C & D & vbLf        Cells(x + 1, 9) = A & B & C & D: x = x + 1     End If         Next N      Next m   Next jNext i   'MsgBox AAEnd Sub
    Editado por osvaldomp

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    SuperBond    3
  • Autor do tópico
  • Ok, obrigado. Existe um comando parecido com 

     

    LR = Cells(Rows.Count, 1).End(xlUp).Row

     

    só que para examinar em coluna, de modo que ele combinasse até o ultimo elemento da linha, independentemente da quantidade? Assim:

     

    post-565727-0-56103200-1421242304.png

     

    post-565727-0-98435800-1421242327.png

     

    post-565727-0-01966100-1421242340.png

     

    Seria analisado conforme o numero de colunas. 

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    osvaldomp    673

    última linha na coluna "C"

    LR = Cells(Rows.Count, 3).End(xlUp).Row   'ouLR = Cells(Rows.Count, "C").End(xlUp).Row


    última linha, independente da coluna em que esteja (os argumentos para "Find" são função do tipo de conteúdo das células)

    LR = UsedRange.Find(What:="*", LookAt:=xlWhole, LookIn:=xlValues, _        SearchDirection:=xlPrevious, SearchOrder:=xlByRows).Row   'ouLR = Cells.Find(What:="*", SearchOrder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).Row   'ouLR = Cells.Find("*", , xlValues, , xlRows, xlPrevious).Row

    última coluna na linha 5

    LC = Cells(5, Columns.Count).End(xlToLeft).Column


    última coluna, independente da linha em que esteja (idem acima, quanto a "Find")

    LC = UsedRange.Find(What:="*", _        LookAt:=xlWhole, LookIn:=xlValues, SearchDirection:=xlPrevious, _        SearchOrder:=xlByColumns).Column

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Crie uma conta ou entre para comentar

    Você precisar ser um membro para fazer um comentário






    Sobre o Clube do Hardware

    No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

    Direitos autorais

    Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

    ×