none
Alinhar duas colunas no MsgBox RRS feed

  • Pergunta

  • Bom dia.

    Tenho duas colunas de uma Tabela como mostrado na figura abaixo, e gostaria de mostrar no Msgbox com as colunas alinhadas, para tanto fiz uma rotina como abaixo, mas nao esta alinhando. Alguem poderia ajudar a verificar onde estou errando?

    Desde ja agradeco

    Tadao

    Sub msgAlinhadas()
    Dim Tb As ListObject
    Dim msg As String
    Dim i As Integer
    Dim s As Integer
    Set Tb = ActiveSheet.ListObjects(1)
    With Tb
                For i = 1 To .ListRows.Count
                            s = .TotalsRowRange(3) + 2 - Len(.ListColumns(1).DataBodyRange.Item(i).Value2)
                            msg = msg & .ListColumns(1).DataBodyRange.Item(i).Value & Space(s) & _
                                        .ListColumns(2).DataBodyRange.Item(i).Value & vbCrLf
                Next i
                MsgBox msg, , "     Nome             Descricao da Planilhas"
    End With
    
    End Sub


    quarta-feira, 23 de janeiro de 2019 07:44

Respostas

  • Boa noite a todos.

    Apenas uma opinião: tentar ajustar colunas com fontes não "mono-space" (seria muito fácil com a "Courier", por exemplo) é uma tarefa hercúlea, e creio não valer o esforço despendido. Penso ser muito mais simples e funcional utilizar um formulário com um ListBox de duas colunas e desenhar a aparência desejada (poderia ser semelhante à janela do MsgBox), além de permitir a inclusão de barras de rolagem, o que é impossível para o método atual.

    Já pensou fazer desta forma?


    Filipe Magno

    quinta-feira, 24 de janeiro de 2019 01:46

Todas as Respostas

  • Bom dia!

    Tente com este exemplo usando vbTab:

    MsgBox "AAAaa" & vbTab & "B" & Chr(10) & "Ccc" & vbTab & "D" & Chr(10) & "EeEeEeEe" & vbTab & "fFfF"


    Natan

    quarta-feira, 23 de janeiro de 2019 09:18
  • Ola Natan, obrigado pelo retorno.

    Ja tinha tentado co vbTab conforme a sua sugestao que ficou como abaixo.

    Modificando a rotina que fiz usando vbTab como abaixo

    Sub msgAlinhadas1()
    'declaracao das variaveis
    Dim Tb As ListObject
    Dim msg As String
    Dim i As Integer
    Dim s As Integer
    
    'definicao da variavel
    Set Tb = ActiveSheet.ListObjects(1)
    
    'com a Tabela
    With Tb
                'da linha 1 ate o final da Tabela, faca
                For i = 1 To .ListRows.Count
                            'concatena duas colunas com vbTab
                            msg = msg & .ListColumns(1).DataBodyRange.Item(i).Value & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(i).Value & vbNewLine
                Next i
                'mostra a variavel com string concatenado
                MsgBox msg, , "     Nome             Descricao das Planilhas"
    End With
    
    End Sub

    ...o resultado ficou como abaixo

    O que deve estar errado?

    Tadao

    quarta-feira, 23 de janeiro de 2019 10:55
  • Tenho notado que se usar o memo comprimento com as mesmas letras, da certo como abaixo

    .....mas se colocar mesmas letras com comprimento diferente, nao funciona como abaixo

    quarta-feira, 23 de janeiro de 2019 11:18
  • inclua essas função em um módulo:

    Public Enum PadMePosition
      
      pmRight = 0
      pmLeft = 1
      pmCenter = 2
    End Enum
    
    Public Function Pad(Texto As String, Tamanho As Byte, Position As PadMePosition, Optional padChar As String = " ") As String
    
        Dim iLen As Integer
        iLen = Len(Texto)
        
        If iLen >= Tamanho Then
          Pad = Left(Texto, Tamanho - 3) & "..."
          Exit Function
        End If
        
        Select Case Position
            Case PadMePosition.pmRight
                Pad = String(Tamanho - iLen, padChar) & Texto
            Case PadMePosition.pmLeft
                Pad = Texto & String(Tamanho - iLen, padChar)
            Case PadMePosition.pmCenter
                esquerda = Int((Tamanho - iLen) / 2)
                direita = Tamanho - esquerda - Len(Texto)
                Pad = String(esquerda, padChar) & Texto & String(direita, padChar)
            Case Else
                Exit Function
        End Select
    
    End Function


    Considerando que você saiba o limite de caracteres da primeira coluna, faça a chamada da msgbox basicamente assim, onde 15 é o limite de caracteres:

      MsgBox Pad("aAaAaAaAa", 15, pmLeft) & vbTab & "1a1a1a1a1a1a1a1a1a1" & chr(10) & _
             Pad("bBbBb", 15, pmLeft) & vbTab & "2b2b2b2b2b2" & chr(10) & _
             Pad("cccCCCCcccc", 15, pmLeft) & vbTab & "3c3C3c3C3cC3"
    

    Resultado:


    Natan

    quarta-feira, 23 de janeiro de 2019 18:46
  • Ola Natan, obrigado pelo pronto retorno.

    Fiz o teste como voce propos, modificando a minha rotina para uma linha da Tabela, deixando como comentario o For Next para nao ir concatenando as Linhas seguintes da Tabela, e funcionou beleza, como mostra a figura abaixo.

    Onde no seu exemplo te aAaAaAa, no meu caso seria a primeira linha da primeira coluna da Tabela com .ListColumns(1).DataBodyRange.Item(i).Value, com i=1, e onde no seu caso e tamanho =15, no meu caso estou indicando a linha de Totais da Tabela onde tem o comprimento Maximo das letras da coluna 1 representado com .TotalsRowRange(3)+2, e por fim o 1a1a1a1a1a1a1 seria a segunda coluna da Tabela com .ListColumns(2).DatabodyRange.Item(i).Value.

    'Rotina para Listar a Descricao das Planilhas
    Sub DescPlan1()
    'declaracao das variaveis
    Dim Tb As ListObject
    Dim msg As String
    Dim i As Integer
    Dim s As Integer
    
    'definicao das variaveis
    Set Tb = Sheets("Miscellaneous").ListObjects(1)
    i = 1
    'com a Tabela
    With Tb
                'da primeira linha ate o final da Tabela, faca
    '            For i = 1 To .ListRows.Count
                            'tamanho do comprimento Maximo das letras da coluna1 +2 menos comprimento da letra de cada linha
                            'concatena as letras das colunas
                            msg = msg & Pad(.ListColumns(1).DataBodyRange.Item(i).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(i).Value & Chr(10)
    '            Next i
                'apresenta a variavel concatenada
                MsgBox msg, , "     Nome             Descricao da Planilhas"
    End With
    End Sub
    

    Mas quando ativo o For Next nao alinha, o que deve ser?

    'Rotina para Listar a Descricao das Planilhas
    Sub DescPlan1()
    'declaracao das variaveis
    Dim Tb As ListObject
    Dim msg As String
    Dim i As Integer
    Dim s As Integer
    
    'definicao das variaveis
    Set Tb = Sheets("Miscellaneous").ListObjects(1)
    i = 1
    'com a Tabela
    With Tb
                'da primeira linha ate o final da Tabela, faca
                For i = 1 To .ListRows.Count
                            'tamanho do comprimento Maximo das letras da coluna1 +2 menos comprimento da letra de cada linha
                            'concatena as letras das colunas
                            msg = msg & Pad(.ListColumns(1).DataBodyRange.Item(i).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(i).Value & Chr(10)
                Next i
                'apresenta a variavel concatenada
                MsgBox msg, , "     Nome             Descricao da Planilhas"
    End With
    End Sub

    quinta-feira, 24 de janeiro de 2019 00:37
  • Boa noite a todos.

    Apenas uma opinião: tentar ajustar colunas com fontes não "mono-space" (seria muito fácil com a "Courier", por exemplo) é uma tarefa hercúlea, e creio não valer o esforço despendido. Penso ser muito mais simples e funcional utilizar um formulário com um ListBox de duas colunas e desenhar a aparência desejada (poderia ser semelhante à janela do MsgBox), além de permitir a inclusão de barras de rolagem, o que é impossível para o método atual.

    Já pensou fazer desta forma?


    Filipe Magno

    quinta-feira, 24 de janeiro de 2019 01:46
  • Ola Felipe, obrigado pelo retorno.

    Esperimentei usar o Courier, mas nao deu resultado nao. Voce tem razao quanto ao ListBox, mas e que da outra vez tb deu o mesmo efeito, entao queria saber o porque da coisa nao funcionar.

    Tadao

    quinta-feira, 24 de janeiro de 2019 09:20
  • Ola Natan, estava testando para ver se tem algo a ver com o For Next, pois no seu exemplo voce colocou as letras diretamente,certo, entao modifiquei a rotina eliminando o For Next mas chamando os dados da Tabela e ficou como abaixo.

    Caracteres alterados para Courier New..

    'Rotina para Listar a Descricao das Planilhas
    Sub DescPlan3()
    'declaracao das variaveis
    Dim Tb As ListObject
    Dim msg As String
    Dim i As Integer
    Dim s As Integer
    
    'definicao das variaveis
    Set Tb = Sheets("Miscellaneous").ListObjects(1)
    i = 1
    'com a Tabela
    With Tb
                'da primeira linha ate o final da Tabela, faca
    '            For i = 1 To .ListRows.Count
                            'tamanho do comprimento Maximo das letras da coluna1 +2 menos comprimento da letra de cada linha
                            'concatena as letras das colunas
                            msg = Pad(.ListColumns(1).DataBodyRange.Item(1).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(1).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(2).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(2).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(3).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(3).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(4).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(4).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(5).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(5).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(6).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(6).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(7).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(7).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(8).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(8).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(8).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(8).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(9).Value, .TotalsRowRange(3) + 2, pmleft) & _
                                        .ListColumns(2).DataBodyRange.Item(9).Value & Chr(10)
    '            Next i
                'apresenta a variavel concatenada
                MsgBox msg, , "     Nome             Descricao da Planilhas"
    End With
    End Sub

    Sera que o problema esta em extrair dados da Tabela?

    Tadao

    quinta-feira, 24 de janeiro de 2019 09:31
  • Tadao, 

    faltou o vbTab

                            msg = Pad(.ListColumns(1).DataBodyRange.Item(1).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(1).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(2).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(2).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(3).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(3).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(4).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(4).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(5).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(5).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(6).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(6).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(7).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(7).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(8).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(8).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(8).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(8).Value & Chr(10) & _
                                        Pad(.ListColumns(1).DataBodyRange.Item(9).Value, .TotalsRowRange(3) + 2, pmLeft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(9).Value & Chr(10)


    Natan

    quinta-feira, 24 de janeiro de 2019 09:56
  • Ohhh.. Natan, um lapso da minha parte... tinha esquecido do vbTab... agora funcionou como esperado conforme a figura abaixo, obrigado

    'Rotina para Listar a Descricao das Planilhas
    Sub DescPlan1()
    'declaracao das variaveis
    Dim Tb As ListObject
    Dim msg As String
    Dim i As Integer
    Dim s As Integer
    
    'definicao das variaveis
    Set Tb = Sheets("Miscellaneous").ListObjects(1)
    i = 1
    'com a Tabela
    With Tb
                'da primeira linha ate o final da Tabela, faca
                For i = 1 To .ListRows.Count
                            'tamanho do comprimento Maximo das letras da coluna1 +2 menos comprimento da letra de cada linha
                            'concatena as letras das colunas
                            msg = msg & Pad(.ListColumns(1).DataBodyRange.Item(i).Value, .TotalsRowRange(3) + 2, pmleft) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(i).Value & Chr(10)
                Next i
                'apresenta a variavel concatenada
                MsgBox msg, , "     Nome             Descricao da Planilhas"
    End With
    End Sub
    

    A sugestao do Felipe tambem e muito boa e fica como a figura abaixo, obrigado.

    quinta-feira, 24 de janeiro de 2019 14:16
  • Ola Natan, obrigado pela ajuda que esta proporcionando.

    Se possivel, gostaria de saber porque quando aumento o comprimento das letras Linha 11), da resultado inesperado?

    Como sou um eterno aprendiz, gostaria se possivel, uma discussao a respeito, que seria:

    Pelo que voce fez a funcao Pad notei que voce concatenou o Texto com a funcao String(Maior tamanho do Texto da Coluna - tamanho do Texto atual , String vazio) Pad = Texto & String(Tamanho - iLen, padChar)

    Alem disso, a sua funcao coloca os ... com o If iLen >= Tamanho Then

    O que observei eh que em vez de usar o Space(s) para acrescentar os vazios, voce colocou os vazios com String() usando a UDR,nao?(por favor, corrija se estou errado).

    Coloquei o vbTab na primeira rotina que fiz e rodei e notei que deu o mesmo resultado ao usado com a sua UDR.

    Sub msgAlinhadas2()
    'declaracao das variaveis
    Dim Tb As ListObject
    Dim msg As String
    Dim i As Integer
    Dim s As Integer
    
    'definicao da variavel
    Set Tb = ActiveSheet.ListObjects(1)
    
    'com a Tabela
    With Tb
                'da linha 1 ate o final da Tabela, faca
                For i = 1 To .ListRows.Count
                            'numero de espaco entre o maior comprimento +2 menos o comprimento da letra atual
                            s = .TotalsRowRange(3) + 2 - Len(.ListColumns(1).DataBodyRange.Item(i).Value2)
                            'concatena com vbCrLf
                            msg = msg & .ListColumns(1).DataBodyRange.Item(i).Value & Space(s) & vbTab & _
                                        .ListColumns(2).DataBodyRange.Item(i).Value & vbCrLf
                Next i
                'mostra a variavel com string concatenado
                MsgBox msg, , "     Nome             Descricao das Planilhas"
    End With
    
    End Sub

    Na sua sugestao como abaixo.....

    Considerando que você saiba o limite de caracteres da primeira coluna, faça a chamada da msgbox basicamente assim, onde 15 é o limite de caracteres:

      MsgBox Pad("aAaAaAaAa", 15, pmLeft) & vbTab & "1a1a1a1a1a1a1a1a1a1" & chr(10) & _
             Pad("bBbBb", 15, pmLeft) & vbTab & "2b2b2b2b2b2" & chr(10) & _
             Pad("cccCCCCcccc", 15, pmLeft) & vbTab & "3c3C3c3C3cC3"

    Resultado:

    ...mas se voce aumenta o limite de caracteres para 20, fica desalinhados

    Sub teste3()
    
      MsgBox Pad("aAaAaAaAa", 20, pmLeft) & vbTab & "1a1a1a1a1a1a1a1a1a1" & Chr(10) & _
             Pad("12345678901234567890", 20, pmLeft) & vbTab & "2b2b2b2b2b2" & Chr(10) & _
             Pad("cccCCCCcccc", 20, pmLeft) & vbTab & "3c3C3c3C3cC3"
             
    End Sub
    

    Voce sabe porque?

    Desde ja agradeco

    Tadao


    sexta-feira, 25 de janeiro de 2019 04:52
  • Natan, obrigado por postar a UDR que posiciona o Texto dentro do Tamanho definido. Vi que usa muitos recursos da Function como ao Argumento Optional que quando omitido coloca a variavel padChar=" " e o argumento Position que retorna uma enumeracao com o Enum listado com pmRight=0 pm left=1 e pmCenter=2. Deu para ter uma boa referencia pois ainda nao domino muito as suas aplicacoes.

    Teste tambem nas planilas, antes convertendo as fontes não "mono-space" conforme sugestao do Felipe e funcionou bem, porem so as emumeracoes Enum nao funcionou, mas no lugar coloquei os numeros e deu certo, nao sei porque.

    Mas todo caso, ficou sem solucao pois acho que tem que mudar a fonte do MsgBox que seria muito trabalhoso e nao valia a pena, portanto vou deixar como resposta a sugestao do Felipe que sugeriu em fazer com Formulario.

    Obrigado

    Tadao

    quarta-feira, 30 de janeiro de 2019 08:48
  • Ola Felipe, obrigado pela sugestao em fazer por formulario que seria mais facil 

    Acho que para dar certo precisa mudar a fonte do MsgBox par o "Courrier" que seria muito trabalhoso, entao vou deixar a sua sugestao como resposta.

    Obrigado

    Tadao

    quarta-feira, 30 de janeiro de 2019 08:54