Página 1 de 1

criar expressão para Ascan

Enviado: 07 Nov 2018 13:53
por Mau_S
Ola Pessoal, meu primeiro post e estou precisando de uma ajuda para criar uma expressão para um array usando o Ascan e assim retornar a posição da informação dentro de um Array.

Segue o exemplo

_aDados := {}

AADD(_aDados,{"Produto","Descricao","00034001","00024401","00325801"})

Assim dentro do Array _aDados eu vou ter

_aDados[1][1] Produto
_aDados[1][2] Descricao
_aDados[1][3] 00034001
_aDados[1][4] 00024401
_aDados[1][5] 00325801

Numa condição que me meu codigo de um fornecedor é o abaixo atribuido a variavel _cFor, aonde o _cFor vai variar de conteudo dentro dos tres codigos acima
_cFor := "00024401"

Como seria a expressão para identificar a posição do conteudo _cFor dentro desse array. Eu sei que nesse exemplo fixo o _cFor que eu citei vai estar sempre na
posição 4, mas esse array do exemplo vai ser dinamico, ou seja, os codigos dentro dele vai sempre variar. Eu vou zera-lo e alimenta-lo a cada looping do meu programa

Vou retornar a posição na variavel _nPos

_nPos := Ascan(_aDados,{|x|x[01] == _cfor})

No caso acima esta errado retorna sempre 0 e eu não sei como montar a expressão de forma correta para retornar a posição correta do codigo.

Agradeço a ajuda

obrigado

criar expressão para Ascan

Enviado: 07 Nov 2018 14:58
por Mau_S
Obrigado, mas não funcionou.

No meu exemplo o Ascan deveria retornar a posição 4(_aDados[1][4]) aonde se encontra o conteudo "00024401" e mesmo montando a expressão conforme seu exemplo ele retorna posição 0

criar expressão para Ascan

Enviado: 07 Nov 2018 16:30
por Mau_S
Cara, muito obrigado por essa idéia, mas nem vai ser preciso tanto.

vendo o seu codigo de como voce tratou o aDados eu vi o meu erro. O meu ascan não funcionou porque ao inves de passar o _aDados como eu fiz eu devo passar
Ascan(_aDados[1],...... porque é a primeira "linha" do array somente.


Muitissimo obrigado :{

criar expressão para Ascan

Enviado: 07 Nov 2018 18:25
por JoséQuintas
Que conversa mais doida.

Se quer comparar o elemento 4, coloca 4 e não 1.

Código: Selecionar todos

nPos := AScan( aDados, { | x | x[ 4 ] == cFor } )

IF nPos != 0
   ? aDados[ nPos, 1 ]
   ? aDados[ nPos, 2 ]
   ? aDados( nPos, 3 ]
   ? aDados[ nPos, 4 ]
   ? aDados[ nPos, 5 ]
ENDIF

criar expressão para Ascan

Enviado: 07 Nov 2018 18:29
por JoséQuintas
E se quer comparar os elementos 3, 4 e 5, coloca 3, 4, e 5

Código: Selecionar todos

nPos := AScan( aDados, { | x | x[ 3 ] == cFor .OR. x[ 4 ] == cFor .OR. x[ 5 ] == cFor } )

criar expressão para Ascan

Enviado: 05 Mai 2021 11:32
por juniorcamilo
JoséQuintas escreveu:E se quer comparar os elementos 3, 4 e 5, coloca 3, 4, e 5

Código: Selecionar todos

nPos := AScan( aDados, { | x | x[ 3 ] == cFor .OR. x[ 4 ] == cFor .OR. x[ 5 ] == cFor } )
bom dia José Quintas!

como eu faria uma ascan com expressão para saber se dentro de uma matriz tem conteúdo, ou seja, c em uma posição da matriz não esta em branco?

criar expressão para Ascan

Enviado: 05 Mai 2021 12:38
por JoséQuintas
Acabo de pensar numa alternativa sobre como decidir isso.
Já comentei antes: codeblock é como função sem nome.
Pense numa função pra isso e coloque igual no codeblock.

Pensando no FOR/NEXT

Código: Selecionar todos

FOR nCont = 1 TO Len( aDados )
   e := aDados[ nCont ]
   Compara( e )
NEXT
Pensando no FOR/EACH

Código: Selecionar todos

FOR EACH e IN aDados
   Compara( e )
NEXT
A função:

Código: Selecionar todos

FUNCTION Compara( e )

   RETURN e[ 1 ] < e[ 2 ]
Isso acima em codeblock, retira o nome da função e o conteúdo é o próprio return.

Código: Selecionar todos

{ | e | e[ 1 ] < e[ 2 ] }
FUNCTION Compara( e ) foi convertido pra | e |
e o RETURN e[ 1 ] < e[ 2 ] foi convertido pra e[ 1 ] < e[ 2 ]
O resultado de ASCAN() vai ser o primeiro que retornar verdadeiro, a posição dele.

Esse "não está em branco", ficou confuso se é combinado com o anterior, ou apenas ver se está em branco, ou ver se um ou todos estão em branco, etc.
Dependendo do que está querendo, por ser assim com .AND., ou com .OR., ou outra coisa

Código: Selecionar todos

Empty( e[ 3 ] ) .AND. Empty( e[ 4 ] ) .AND. Empty( e[ 5 ] )

criar expressão para Ascan

Enviado: 05 Mai 2021 12:40
por JoséQuintas
Ok, vi depois que é no fórum Clipper, o exemplo de FOR/EACH não vale pra Clipper, só pra Harbour, mas já fica sabendo que existe a opção.

criar expressão para Ascan

Enviado: 06 Mai 2021 07:45
por juniorcamilo
JoséQuintas escreveu: Esse "não está em branco", ficou confuso se é combinado com o anterior, ou apenas ver se está em branco, ou ver se um ou todos estão em branco, etc.
EMPTY() MESMO, ou seja, exemplo basico!

Código: Selecionar todos

...
aMatriz := {{},{},{},{}}
for nCont = 1 to Len(aMatriz[1])
    if !empty(Matriz[3,nCont]) 
       exit
    endif
next
....
como ficaria isso no ascan? sei q esta no forum de clipper! mas pode apresentar se necessário também para xharbour!

desde ja agradeço pela atenção!

criar expressão para Ascan

Enviado: 06 Mai 2021 12:09
por JoséQuintas

Código: Selecionar todos

...
aMatriz := {{},{},{},{}}
for nCont = 1 to Len(aMatriz[1])
    if !empty(Matriz[3,nCont]) 
       exit
    endif
next
....
Tentar entender.... porque acho que o FOR/NEXT tá errado, talvez só a inversão 3,nCont, pra nCont,3 ou talvez mais que isso.

A impressão que tenho é que está querendo ver os arrays de dentro e não o array de fora.

Código: Selecionar todos

FOR nCont = 1 TO Len( aMatriz )
   Funcao( aMatriz[ 1 ] )  // processa um elemento por vez, que tem 4 arrays
NEXT
...
FUNCTION Funcao( e )

   FOR nCont = 1 TO Len( e[ 1 ] )
      IF ! Empty( e[ 3 ] ) // olha se no array 3, a mesma posição do 1 está vazia
         EXIT
     ENDIF
   NEXT
... 
RETURN Nil

criar expressão para Ascan

Enviado: 06 Mai 2021 12:19
por JoséQuintas

Código: Selecionar todos

...
aMatriz := {{},{},{},{}}
for nCont = 1 to Len(aMatriz[1])
    if !empty(Matriz[3,nCont]) 
       exit
    endif
next
....
Ok, ainda tentando entender...
Parece que pega da matriz 1, se na matriz 3 não estiver vazio.

Código: Selecionar todos

nPos := hb_AScan( aMatriz[ 3 ], { | e | ! Empty( e ) } )
? aMatriz[ 1 ][ nPos ]

criar expressão para Ascan

Enviado: 06 Mai 2021 12:24
por JoséQuintas
Ou pra simplificar, ainda tentando entender...
{ aLista1, aLista2, aLista3, aLista4 }, onde cada um é um array

Código: Selecionar todos

aMatriz := { {}, {}, {}, {} }
aLista1 := aMatriz[ 1 ]
aLista2 := aMatriz[ 2 ]
aLista3 := aMatriz[ 3 ]
aLista4 := aMatriz[ 4 ]
nPos := ASCan( aLista3, { | e | ! Empty( e ) } )
? aLista1[ nPos ]
É o mesmo anterior, apenas dei nome a cada lista.
É o que o seu FOR/NEXT sugere sobre o que está querendo fazer.
Neste aqui chamei de lista1,2,3,4, mas no anterior usei direto aMatriz[ 1 ] e aMatriz[ 3 ]

criar expressão para Ascan

Enviado: 06 Mai 2021 12:39
por JoséQuintas
Precisa confirmar sobre o array.
Poderia ser:

Código: Selecionar todos

{ { codigo, codigo, codigo }, { nome, nome, nome }, { valor, valor, valor } )
ou

Código: Selecionar todos

{ { codigo, nome, valor }, { codigo, nome, valor }, { codigo, nome, valor } )
Pra achar qual tem valor zero, depende de como ele está distribuído, se da primeira forma ou da segunda.

criar expressão para Ascan

Enviado: 06 Mai 2021 12:54
por JoséQuintas
No primeiro caso, que cada campo está numa lista, é pesquisar na LISTA DE VALORES, e pegar o nome da LISTA DE NOMES

Código: Selecionar todos

nPos := AScan( array[ 3 ], { | e | e != 0 } ) // pesquisa a coluna 3=lista de valores
cNome := array[ 2 ][ nPos ] // pega da coluna 2=lista de nomes
No segundo caso, é olhar cada um da LISTA, e pegar o CAMPO NOME dessa lista

Código: Selecionar todos

nPos := ASCan( array, { | e | e[ 3 ] != 0 } ) // pesquisa na lista geral em cada elemento, a coluna 3=valor
cNome := array[ nPos ] [ 2 ] // pega da lista geral coluna 2=nome
Chamando de lista, e do que tem em cada lista, parece ficar mais claro

Nota: array[ nPos, 2 ] e array[ nPos ][ 2 ] são equivalentes, pode escrever dos dois jeitos.
Mas array[ nPos, 2 ] é diferente de array[ 2, nPos ], são posições diferentes.

criar expressão para Ascan

Enviado: 07 Mai 2021 09:40
por juniorcamilo

Código: Selecionar todos

   
  if AScan( aMatEntrada[27],{ | e | ! Empty( e ) }) # 0
       ........
  endif

funcionou perfeitamente!
obrigado pela excelente aula!