criar expressão para Ascan

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Mau_S
Usuário Nível 1
Usuário Nível 1
Mensagens: 3
Registrado em: 07 Nov 2018 12:06
Localização: Cerquilho SP

criar expressão para Ascan

Mensagem 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
Mau_S
Usuário Nível 1
Usuário Nível 1
Mensagens: 3
Registrado em: 07 Nov 2018 12:06
Localização: Cerquilho SP

criar expressão para Ascan

Mensagem 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
Mau_S
Usuário Nível 1
Usuário Nível 1
Mensagens: 3
Registrado em: 07 Nov 2018 12:06
Localização: Cerquilho SP

criar expressão para Ascan

Mensagem 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 :{
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

criar expressão para Ascan

Mensagem 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
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

criar expressão para Ascan

Mensagem 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 } )
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
juniorcamilo
Usuário Nível 3
Usuário Nível 3
Mensagens: 343
Registrado em: 10 Nov 2006 09:12
Localização: Pará

criar expressão para Ascan

Mensagem 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?
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

criar expressão para Ascan

Mensagem 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 ] )
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

criar expressão para Ascan

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
juniorcamilo
Usuário Nível 3
Usuário Nível 3
Mensagens: 343
Registrado em: 10 Nov 2006 09:12
Localização: Pará

criar expressão para Ascan

Mensagem 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!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

criar expressão para Ascan

Mensagem 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
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

criar expressão para Ascan

Mensagem 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 ]
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

criar expressão para Ascan

Mensagem 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 ]
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

criar expressão para Ascan

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

criar expressão para Ascan

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
juniorcamilo
Usuário Nível 3
Usuário Nível 3
Mensagens: 343
Registrado em: 10 Nov 2006 09:12
Localização: Pará

criar expressão para Ascan

Mensagem por juniorcamilo »

Código: Selecionar todos

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

funcionou perfeitamente!
obrigado pela excelente aula!
Responder