Olá!
Segue a minha versão da rotina:
// Preciso ler uma (string/Texto) que na verdade está armazenando dezenas,
// e que está separada por PIPE
// Preciso saber quantas vezes e quais números repetem nela, separados por PIPE |
#include "setcurs.ch"
PROCEDURE Duplicados()
// Alexandre Santos - Fórum PC Toledo
LOCAL cDup, cString, nLimit, nOuter, cSearch
LOCAL nCount, nInner, nOffSet, cOldColor, nOldCursor
RELEASE GetList
REQUEST DBFCDX
RDDSETDEFAULT( "DBFCDX" )
cOldColor := SetColor( "W+/B,B/W" ) ; CLS
nOldCursor := SC_NONE
If ! File( "DEZENAS.DBF" )
DbCreate("Dezenas", { { "Dezenas", "C", 29, 0 }, { "Duplicados", "C", 80, 0 } }, "DBFCDX" )
DBUSEAREA( .T., "DBFCDX", "DEZENAS", "DEZENAS", .F. )
DbAppend() ; DEZENAS->dezenas := "17|20|22|27|30|35|41|42|75|95"
DbAppend() ; DEZENAS->dezenas := "71|16|25|34|70|27|80|43|61|06"
DbAppend() ; DEZENAS->dezenas := "04|12|17|29|39|43|48|67|69|81"
DbAppend() ; DEZENAS->dezenas := "95|94|98|97|08|77|83|84|85|20"
DbAppend() ; DEZENAS->dezenas := "01|01|01|01|01|01|01|01|01|01"
DbAppend() ; DEZENAS->dezenas := "04|06|08|12|17|28|29|39|79|86"
DbAppend() ; DEZENAS->dezenas := "11|18|23|27|39|43|49|74|77|84"
DbAppend() ; DEZENAS->dezenas := "27|95|06|35|61|56|98|49|17|01"
DbAppend() ; DEZENAS->dezenas := "43|16|74|56|84|08|34|55|69|06"
DbAppend() ; DEZENAS->dezenas := "01|06|09|16|35|49|62|70|89|99"
DbAppend() ; DEZENAS->dezenas := "18|17|38|98|06|02|43|22|49|27"
DbAppend() ; DEZENAS->dezenas := "27|06|32|35|75|81|08|29|52|56"
DbAppend() ; DEZENAS->dezenas := "06|18|23|35|38|60|71|89|95|98"
DbAppend() ; DEZENAS->dezenas := "09|27|23|02|95|12|78|41|60|77"
DbAppend() ; DEZENAS->dezenas := "04|17|20|38|42|56|61|79|83|95"
DbAppend() ; DEZENAS->dezenas := "67|42|02|56|77|98|24|52|86|61"
DbAppend() ; DEZENAS->dezenas := "11|01|18|22|34|42|56|66|75|92"
DbAppend() ; DEZENAS->dezenas := "69|69|69|69|69|69|69|69|69|69"
DbAppend() ; DEZENAS->dezenas := "82|52|08|18|11|67|84|66|70|80"
DbAppend() ; DEZENAS->dezenas := "11|69|38|23|28|62|66|08|77|21"
DbAppend() ; DEZENAS->dezenas := "01|01|01|01|01|01|01|01|01|01"
DbAppend() ; DEZENAS->dezenas := "08|11|12|20|21|55|69|70|80|96"
DbAppend() ; DEZENAS->dezenas := "16|16|16|16|16|16|16|16|16|16"
DbAppend() ; DEZENAS->dezenas := "16|16|16|16|16|16|16|16|16|16"
DbAppend() ; DEZENAS->dezenas := "17|21|32|39|48|63|70|79|55|84"
DbAppend() ; DEZENAS->dezenas := "32|21|48|15|99|22|83|35|97|25"
DbAppend() ; DEZENAS->dezenas := "11|16|18|30|34|93|94|71|70|69"
DbAppend() ; DEZENAS->dezenas := "01|04|09|17|27|36|43|81|83|97"
DbAppend() ; DEZENAS->dezenas := "49|56|20|52|62|63|74|70|40|66"
DbAppend() ; DEZENAS->dezenas := "11|96|32|22|21|84|35|06|62|18"
DbAppend() ; DEZENAS->dezenas := "09|98|11|35|85|29|75|52|32|30"
DbAppend() ; DEZENAS->dezenas := "25|28|35|60|61|11|11|12|16|78"
DbAppend() ; DEZENAS->dezenas := "02|08|15|22|29|42|55|69|82|89"
DbAppend() ; DEZENAS->dezenas := "55|08|15|02|29|08|55|15|42|08"
// 0...x....1....x....2....x...2
// 12345678901234567890123456789
Else
DBUSEAREA( .T., "DBFCDX", "DEZENAS", "DEZENAS", .F. )
Endif
DEZENAS->( DbGoTop() )
nOffSet := 3
// percorre os registros
While ! DEZENAS->( Eof() )
cDup := ""
cString := DEZENAS->dezenas
nLimit := Len( cString )
nOuter := 1
// loop externo... percorre as dezenas de cada registro
While nOuter < nLimit
cSearch := SubStr( cString, nOuter, 2 )
nInner := 1
nCount := 0
// loop interno... conta cada dezena nas dezenas do registro atual
While nInner < nLimit
If Substr( cString, nInner, 2 ) == cSearch
nCount++
Endif
nInner += nOffSet
Enddo
// se encontrou mais que um
If nCount > 1
// se é a primeira vez que encontrou, guarda
If At( cSearch + ":", cDup ) == 0
cDup += If( ! Empty( cDup ), ", ", "" ) + cSearch + ":" + LTrim( Str( nCount ) )
Endif
Endif
nOuter += nOffSet
Enddo // nOuter < nLimit
// se encontrou, grava no próprio registro (arquivo aberto em modo exclusivo)
If ! Empty( cDup )
DEZENAS->Duplicados := cDup
Endif
// avança registro
DEZENAS->( DbSkip() )
Enddo // ! DEZENAS->( Eof() )
// exibe registros, fecha arquivo
DEZENAS->( Browse(), DbCloseArea() )
// restaura tela
SetColor( cOldColor ) ; CLS ; SetCursor( nOldCursor )
RETURN
//----------------------------------------------------------------------------------------------------
JoséQuintas escreveu:A função Split ficou meio confusa.
Segue a minha versão:
//----------------------------------------------------------------------------------------------------
FUNCTION aTokens( cString, cDelimiter )
// Alexandre Santos - Fórum PC Toledo
LOCAL aTokens := {}, nPos, nLen
If Valtype( cString ) == "C" .And. ( ! Empty( cString := Alltrim( cString ) ) )
If Valtype( cDelimiter ) == "C" .And. ( ! Empty( cDelimiter ) )
While ( nPos := At( cDelimiter, cString ) ) > 0
AAdd( aTokens, SubStr( cString, 1, nPos - 1 ) )
cString := SubStr( cString, nPos + 1 )
Enddo
AAdd( aTokens, cString )
Else
// sem delimitador... retorna byte a byte
nLen := Len( cString )
For nPos := 1 To nLen
AAdd( aTokens, SubStr( cString, nPos, 1 ) )
Next
Endif
Endif
RETURN aTokens
//----------------------------------------------------------------------------------------------------
informais escreveu:Preciso saber quantas vezes e quais números repetem nela, separados por PIPE |
Não ficou claro se o retorno também é uma string com o resultado separado por pipes. Mas isto é fácil de adaptar...