aSort com valor negativo + texto

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Junior
Usuário Nível 1
Usuário Nível 1
Mensagens: 25
Registrado em: 19 Ago 2003 17:44
Localização: Bragança Paulista

aSort com valor negativo + texto

Mensagem por Junior »

Bom dia, Srs !

Estou enfrentando uma dificuldade na ordenação de uma array com apenas 2 elementos, sendo um numérico e outro texto. O elemento numérico apresenta valores negativos que devem estar em primeiro na ordenação. Quanto menor, mais importante.

Código: Selecionar todos

Curva   Valor
A2      -100
A1       200
A3      -300
A1      -300
O Exemplo acima mostra os valores desordenados, abaixo os ordenados, respeitando sempre VALOR + CURVA:

Código: Selecionar todos

Curva  Valor
A1      -300
A3      -300
A2      -100
A1       200
Porém, o bendito do ASORT não entende assim, ele faz uma mescla de bagunça na ordenação que eu ainda não consegui entender. Já tentei concatenar valores com ASC, STR mas não adianta. A única ordenação correta é quando eu passo apenas o elemento numérico, sem considerar o texto (curva).

Funciona:

Código: Selecionar todos

aSort(aDados02,,, {|x,y| x[1] < y[1]})
Não funciona:

Código: Selecionar todos

aSort(aDados02,,, {|x,y| STR(x[1])+y[2] < STR(y[1])+y[2]})
aSort(aDados02,,, {|x,y| x[1]+ASC(y[2]) < y[1]+ASC(y[2])})
Ou seja, ao que parece o ASORT pira quando concateno elementos de tipos diferentes quando o elemento numérico possui valores negativos.

Alguma luz?

Vale lembrar que esse "não funciona", apenas não funciona mesmo quando existem valores negativos no elemento numérico, para números positivos, quando eu concateno com STR(), tudo fica OK!

Obrigado sempre por tudo, já frequentei essa comunidade há muito tempo atrás, uma pena os rumos da vida nos indicarem outras linguagens.

Abraço a todos !
Junior
Source com farinha....
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

aSort com valor negativo + texto

Mensagem por Toledo »

Amigo, tente o seguinte:

Código: Selecionar todos

aSort(aDados02,,, {|x,y| STR(x[2])+x[1] < STR(y[2])+y[1]})
No seu exemplo, observe que você está usando STR(x[1])+y[2] < STR(y[1])+y[2]}), misturando elementos x e y numa mesma combinação. E também, se na matriz o segundo elemento é o valor, então STR() tem que ser usado com o elemento 2.

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Junior
Usuário Nível 1
Usuário Nível 1
Mensagens: 25
Registrado em: 19 Ago 2003 17:44
Localização: Bragança Paulista

aSort com valor negativo + texto

Mensagem por Junior »

Toledo! Prazer em falar com você novamente.

Amigo, peço perdão pelo equívoco, foi um erro de digitação, na verdade o elemento X é sim comparado com o elemento Y:

Código: Selecionar todos

aSort(aDados02,,, {|x,y| STR(x[2],12,2)+x[1] < STR(y[2],12,2)+y[1]})
O código acima só funciona quando o elemento numérico apresenta valores positivos, já se algum negativo for encontrado, a ordenação fica maluca.

Obrigado pelo retorno e um abraço!
Junior
Source com farinha....
sambomb
Usuário Nível 3
Usuário Nível 3
Mensagens: 250
Registrado em: 24 Out 2008 17:02
Localização: Itaocara - RJ - Brasil

aSort com valor negativo + texto

Mensagem por sambomb »

Código: Selecionar todos

aSort(aDados02,,, {|x,y| If(x[2]<0,"A","B")+STR(Abs(x[2]),12,2)+x[1] < If(y[2]<0,"A","B")+STR(Abs(y[2]),12,2)+y[1]})
Tente assim
Coloquei um texto padrão para negativos ( A ) e para positivos ( B ) e removi o módulo do valor original.
Assim ficará da seguinte forma:

Código: Selecionar todos

1	Curva  Valor Texto para comparação
2	A1      -300   A300A1
3	A3      -300   A300A3
4	A2      -100   A300A2
5	A1       200   B200A1
Imagem

Rca Sistemas - Itaocara - RJ
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

aSort com valor negativo + texto

Mensagem por Jairo Maia »

Olá Júnior,

Se a sugestão do Samir também não funcionar (testei aqui e não deu), não vejo outra forma pra você ter esse resultado senão ardenando os campos separadamente. Tente assim e veja se funciona:

Código: Selecionar todos

aSort( aDados02,,, { |x,y| x[1] < y[1]  } )  // ordena o primeiro elemento
aSort( aDados02,,, { |x,y| x[2] < y[2]  } )  // depois ordena o segundo elemento
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1297
Registrado em: 06 Jul 2004 00:44
Contato:

aSort com valor negativo + texto

Mensagem por ANDRIL »

Junior escreveu:Alguma luz?
Compare a matriz com todos os 2 elementos, tente assim:

Código: Selecionar todos

aSort(aDados02,,,{|x,y| x[1]<y[1].and.x[2]<y[2]})
Ate+
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

aSort com valor negativo + texto

Mensagem por Eolo »

Junior,
Se a ASORT() tá fazendo doce, engane ela!
Testei aqui e funcionou perfeito.

A idéia:
- identifique o menor valor negativo (no caso, -300)
- some 300 em todos os elementos da matriz
- o menor valor, então, se transforma em ZERO
- e agora a matriz não tem mais números negativos
- aplique o ASORT
- subtraia 300 em todos os elementos da matriz
- feito.

Código: Selecionar todos

mat:={}
aadd(mat,{"a2",-100})
aadd(mat,{"a1", 200})
aadd(mat,{"a3",-300})
aadd(mat,{"a1",-300})
const=0
* APONTA O MENOR VALOR
for x=1 to len(mat)
  min(const,mat[x,2])
next
* CONST vai conter -300
* MOSTRA VALORES DESORDENADOS
for x=1 to len(mat)
  ?mat[x,1]
  ?mat[x,2]
next
if const<0
  for x=1 to len(mat)
    * MENOR VALOR PASSA A SER ZERO
    * SOMEM OS VALORES NEGATIVOS
    mat[x,2]:=mat[x,2]+const
  next
endi
* ORDENA CONFORME DESEJADO

*mat:=aSort(mat,,, {|x,y| x[2] < y[2]})

* pegando carona na sugestão do ANDRIL
mat:=aSort(mat,,,{|x,y| x[1]<y[1].and.x[2]<y[2]})

if const<0
  for x=1 to len(mat)
    * FAZ VALORES VOLTAR AOS VALORES ORIGINAIS, COM OS NEGATIVOS
    mat[x,2]:=mat[x,2]-const
  next
endi
* MOSTRA VALORES ORDENADOS CONFORME DESEJADO
for x=1 to len(mat)
  ?mat[x,1]
  ?mat[x,2]
next
Junior
Usuário Nível 1
Usuário Nível 1
Mensagens: 25
Registrado em: 19 Ago 2003 17:44
Localização: Bragança Paulista

aSort com valor negativo + texto

Mensagem por Junior »

Bom dia, amigos !

@sambomb
A mehor solução até o momento, boa ideia. Converter os conteúdos em uma string única e depois ordena-la, realmente funcionou com alguns ajustes, veja:

Código: Selecionar todos

Iif(x[2]<0,STRTRAN("A"+STR(ABS(100000+x[2]),12,2)+x[1],".",""), STRTRAN("B"+STR(x[2],12,2)+x[1],".",""))
A lógica é continuar gerando uma string única, aonde os negativos sejam ordenados em prioridade, porém, quanto maior negativo, maior a prioridade, então calculei sobre 100000 o valor negativo e o inverti, ordenando-o pelo resultado encontrato no cálculo. Funcionou mil maravilhas.

@Jairo
Infelizmente não deu certo pois a execução do 2o asort anula o 1o. Ele sempre reposiciona os elementos de acordo com as condições passadas no asort, eliminando a ordenação anterior.

@ANDRIL
Também não funcionou, o asort continuou maluco.

@Eolo
Sua ideia realmente funciona, mas achei um pouco redundante em sua execução. Pra um relatório com cálculos grandes como o que estou processando, acho que não seria viável pela lógica necessária.

A todos, meu agradecimento pela ajuda fornecida. Sei que posso contar com esse fórum sempre que preciso e fico feliz em saber que ele ainda está de pé e tem um futuro imenso pela frente. Pretendo passar mais por aqui pra ajudar no suporte, porém, a correria do dia a dia dita o que consigo fazer e o que não, mas vou me esforçar!

Abraço a todos!
Junior
Source com farinha....
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

aSort com valor negativo + texto

Mensagem por Eolo »

Junior,

Vc não deixou claro que a matriz era muito grande.

Bem, se os dados são muitos, acredito que estão em um DBF. Então, não seria melhor voltar um passo, rever a CRIAÇÃO da matriz?

Com um INDEX adicional no DBF ("str(valor)+curva"), vc já criaria a matriz na ordem desejada, podendo dispensar o uso da ASORT e suas limitações.

Abrss
Junior
Usuário Nível 1
Usuário Nível 1
Mensagens: 25
Registrado em: 19 Ago 2003 17:44
Localização: Bragança Paulista

aSort com valor negativo + texto

Mensagem por Junior »

Amigo Eolo,

Desculpe-me se me expressei de maneira incorreta, o exemplo passado no primeiro post nada mais é que um exemplo mesmo, bem simples. Não trabalho com DBF, nesse caso em específico preciso gerar um relatório em Excel para o cliente aonde cada grupo de produto é uma sheet, então, com os dados em mãos já devidamente filtrados em SQL, adiciono cada registro em sua array definida, ordenando depois no momento da geração da planilha. Não consigo gerar a planilha se não passar uma array pra cada sheet. O código é utilizado em ADVPL, linguagem de um sistema ERP chamado Microsiga, atualmente mais conhecido como TOTVS.
Assim sendo, se o cliente possui 200 grupos, crio 200 sheets de excel, cada uma com sua array pra não precisar ficar filtrando uma array única por grupo e etc... então, pra eu recalcular a array, removendo valor negativo, adicionando valor positivo, for/next nesses casos iriam comprometer a performance, entende ?

Novamente me desculpe se não fui suficientemente claro.

Abraço!
Source com farinha....
sambomb
Usuário Nível 3
Usuário Nível 3
Mensagens: 250
Registrado em: 24 Out 2008 17:02
Localização: Itaocara - RJ - Brasil

aSort com valor negativo + texto

Mensagem por sambomb »

Realmente tinha uma falha no meu código que era que após removido o módulo ele inverteria a ordenação, o menor ao invés de ser -300 ia passar a ser o maior enquanto o maior -100 iria ser o menor.

Mas que bom que minha solução resolveu de ponto inicial para a solução definitiva!
Imagem

Rca Sistemas - Itaocara - RJ
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

aSort com valor negativo + texto

Mensagem por Eolo »

com os dados em mãos já devidamente filtrados em SQL
Junior,
Sou zero à esquerda em SQL, a pergunta vai parecer sem nexo, mas aqui vai (pra eu aprender): na filtragem, vc não pode pedir ao SQL pra já ordenar os dados filtrados (por grupo de produto, valor e curva)? Se sim, o uso da ASORT poderia ser inclusive eliminado.
Abrss
Junior
Usuário Nível 1
Usuário Nível 1
Mensagens: 25
Registrado em: 19 Ago 2003 17:44
Localização: Bragança Paulista

aSort com valor negativo + texto

Mensagem por Junior »

Boa tarde, Eolo!

O cálculo do valor é feito no momento da execução da rotina, ele não existe em base de dados. Primeiro é feio todo um levantamento mensal sobre o que produzir, calculam-se metas, médias, faturamentos, previsões e por ultimo a prioridade é definida, é por ela que o sistema indica o que e quando fabricar. Já ouviu falar na sistemática de Kanban ? É uma técnica japonesa, muitas indústrias utilizam pois ele é um ponto importante no momento de produção, principalmente na orientação do chão de fábrica.

Quanto menor a prioridade(inclusive negativa), maior é a necessidade de fabricar. No Kanban, o menor sempre é maior.

Abraço!
Source com farinha....
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

aSort com valor negativo + texto

Mensagem por Eolo »

Junior,

Há uns tempos ouvi sobre um tal de KanbanFlow, agora o nome eu já sei de onde vem :-)

Eu nunca trabalhei em produção industrial, deve ser algo muito legal. E mais legal ainda é ver um software da gente organizando informações e alimentando um processo do tipo, né não? Parabéns!

Abrss
Responder