Usuário com melhor resposta
Alinhar duas colunas no MsgBox

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
- Editado Antonio Tadao kano quarta-feira, 23 de janeiro de 2019 07:45
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
- Marcado como Resposta Antonio Tadao kano quarta-feira, 30 de janeiro de 2019 08:50
Todas as Respostas
-
-
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
-
-
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
-
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
-
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
- Marcado como Resposta Antonio Tadao kano quarta-feira, 30 de janeiro de 2019 08:50
-
-
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
-
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
- Marcado como Resposta Antonio Tadao kano quinta-feira, 24 de janeiro de 2019 14:16
- Não Marcado como Resposta Antonio Tadao kano sexta-feira, 25 de janeiro de 2019 02:51
-
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.
-
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
-
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
-
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