Página 1 de 1

abreviar nomes

Enviado: 16 Set 2016 12:36
por kakamachado
Bom dia colegas, alguém tem um rotina ou função que abrevie nomes próprios (pessoas), por exemplo, de 60 para 30 caracteres? Deve manter o primeiro e o último nome sem abreviar.
Obrigado

abreviar nomes

Enviado: 17 Set 2016 23:46
por wmanesco
Boa noite

Seria isso?

Código: Selecionar todos


FUNCTION AbreviarNome( cNomeCompleto )
   LOCAL cAbreviacao
   LOCAL aNome, cNome

   aNome := HB_ATokens( Alltrim( cNomeCompleto ), " " )

   cAbreviacao := ""
   FOR EACH cNome IN aNome
      IF Empty( cNome )
         LOOP
      ENDIF

      IF HB_EnumIndex( cNome ) == 1 .OR. HB_EnumIndex( cNome ) == Len( aNome ) .OR. Len( cNome ) <= 3
         cAbreviacao += " " + cNome
      ELSE
         cAbreviacao += " " + Left( cNome, 1 ) + "."
      ENDIF
   NEXT

RETURN cAbreviacao

abreviar nomes

Enviado: 19 Set 2016 13:11
por alxsts
Olá!

Aparentemente o código postado atenderá a solicitação.

Há muito tempo precisei desenvolver uma rotina destas mas não tenho o fonte, pois ficou no cliente. A única observação que faço é a seguinte: quando o último sobrenome for "Junior","Jr","Jr.","Filho","Neto","Sobrinho","Sobr.","Netto", etc, o penúltimo sobrenome não poderá ser abreviado.

abreviar nomes

Enviado: 19 Set 2016 13:31
por fladimir
Ótima Observação Alexandre... vlw

abreviar nomes

Enviado: 19 Set 2016 14:22
por wmanesco
Realmente não tinha pensado nesta hipótese, obrigado

abreviar nomes

Enviado: 19 Set 2016 16:21
por kakamachado
Boa tarde Wmanesco, Fladimir e Alxsts, obrigado pelas colaborações. Fiz uma alteração na função, pois me expressei mal na demanda. Precisava que os nomes fossem abreviados somente se o nome completo ultrapassasse 30 caracteres e mantendo o primeiro e o último sem abreviar. Ex: JOAO CARLOS DA SILVA PEREIRA CONSTANTINO (40 CARACTERES) ficaria JOAO CARLOS DA S P CONSTANTINO (30 CARACTERES) não precisando abreviar o CARLOS. Valeu galera.

abreviar nomes

Enviado: 20 Set 2016 00:38
por alxsts
Olá!

A verdade é que 30 caracteres para armazenar nomes de pessoas é pouco espaço. Mesmo abreviando, é possível que ultrapasse este limite. O que fazer? Truncar? Creio que não seja a melhor solução...

abreviar nomes

Enviado: 20 Set 2016 01:12
por JoséQuintas
Achei interessante o desafio.

Código: Selecionar todos

PROCEDURE Main

   LOCAL nCont, cNome := "JOSE MARIA CUNHA HARBOUR PROGRAMMER OF QUINTAS"

   FOR nCont = 10 TO 70 STEP 5
      ? AbreviarNome( cNome, nCont )
   NEXT

   RETURN

FUNCTION AbreviarNome( cNaoAbreviado, nTamanho )

   LOCAL aNomeLst, cAbreviado := "", oElement, nCont, nQtNaoAbreviado, nTentativas := 0, lTiraInutil := .T., nLimit

   hb_Default( @nTamanho, Len( cNaoAbreviado ) )

   aNomeLst := hb_RegExSplit( " ", cNaoAbreviado )

   IF Len( aNomeLst ) > 2
      DO WHILE .T.
         cAbreviado := ""
         nQtNaoAbreviado := 0
         FOR EACH oElement IN aNomeLst
            cAbreviado += oElement + " "
            nQtNaoAbreviado += iif( Len( oElement ) < 4, 0, 1 )
         NEXT
         DO CASE
         CASE Len( cAbreviado ) <= nTamanho
         CASE nQtNaoAbreviado < 3
         CASE lTiraInutil
            FOR EACH oElement IN aNomeLst
               IF oElement == "OF" .OR. oElement == "DE" .OR. oElement == "DO" .OR. oElement == "DA" .OR. oElement == "DAS" .OR. oElement == "DOS"
                  aDel( aNomeLst, oElement:__EnumIndex )
                  aSize( aNomeLst, Len( aNomeLst ) - 1 )
               ENDIF
            NEXT
            lTiraInutil := .F.
            LOOP
         CASE nTentativas > 20
         OTHERWISE
            nLimit := Len( aNomeLst ) - iif( aNomeLst[ Len( aNomeLst ) ] $ "JUNIOR,JR,FILHO,NETO", 2, 1 )
            IF nLimit > 2
               FOR nCont = nLimit TO 2 STEP -1
                  IF Len( aNomeLst[ nCont ] ) > 2
                     aNomeLst[ nCont ] := Left( aNomeLst[ nCont ], 1 ) + "."
                     EXIT
                  ENDIF
               NEXT
            ENDIF
            nTentativas += 1
            LOOP
         ENDCASE
         EXIT
      ENDDO
   ENDIF
   cAbreviado := Pad( cAbreviado, nTamanho )

   RETURN cAbreviado

Código: Selecionar todos

JOSE M. C.
JOSE M. C. H. P
JOSE M. C. H. P. QUI
JOSE M. C. H. P. QUINTAS
JOSE MARIA C. H. P. QUINTAS
JOSE MARIA CUNHA H. P. QUINTAS
JOSE MARIA CUNHA HARBOUR P. QUINTAS
JOSE MARIA CUNHA HARBOUR PROGRAMMER QUINTAS
JOSE MARIA CUNHA HARBOUR PROGRAMMER OF QUINTAS
JOSE MARIA CUNHA HARBOUR PROGRAMMER OF QUINTAS
JOSE MARIA CUNHA HARBOUR PROGRAMMER OF QUINTAS
JOSE MARIA CUNHA HARBOUR PROGRAMMER OF QUINTAS
JOSE MARIA CUNHA HARBOUR PROGRAMMER OF QUINTAS

abreviar nomes

Enviado: 20 Set 2016 02:18
por JoséQuintas
Compliquei um pouco mais: abrevia do centro pras bordas.
Peguei só um pedaço do nome de D.Pedro pra testar

Código: Selecionar todos

PROCEDURE Main

   LOCAL nCont, cNome := "PEDRO DE ALCANTARA FRANCISCO ANTONIO JOAO CARLOS XAVIER DE PAULA MIGUEL RAFAEL JOAQUIM"

   FOR nCont = 100 TO 10 STEP -5
      ? AbreviarNome( cNome, nCont )
   NEXT

   RETURN

FUNCTION AbreviarNome( cNaoAbreviado, nTamanho )

   LOCAL aNomeLst, cAbreviado := "", oElement, nCont, nQtNaoAbreviado, nTentativas := 0, lTiraInutil := .T., anNao, nMeio

   hb_Default( @nTamanho, Len( cNaoAbreviado ) )

   aNomeLst := hb_RegExSplit( " ", cNaoAbreviado )

   IF Len( aNomeLst ) > 2
      DO WHILE .T.
         cAbreviado := ""
         nQtNaoAbreviado := 0
         FOR EACH oElement IN aNomeLst
            cAbreviado += oElement + " "
            nQtNaoAbreviado += iif( Len( oElement ) < 4, 0, 1 )
         NEXT
         DO CASE
         CASE Len( cAbreviado ) <= nTamanho
         CASE nQtNaoAbreviado < 3
         CASE lTiraInutil
            FOR EACH oElement IN aNomeLst
               IF oElement == "E" .OR. oElement == "DE" .OR. oElement == "DO" .OR. oElement == "DA" .OR. oElement == "DAS" .OR. oElement == "DOS"
                  aDel( aNomeLst, oElement:__EnumIndex )
                  aSize( aNomeLst, Len( aNomeLst ) - 1 )
               ENDIF
            NEXT
            lTiraInutil := .F.
            LOOP
         CASE nTentativas > 50
         OTHERWISE
            anNao := { 1, Len( aNomeLst ), iif( aNomeLst[ Len( aNomeLst ) ] $ "JUNIOR,JR,FILHO,NETO,SOBRINHO", Len( aNomeLst ) - 1, 1 ) }
            nMeio := Round( Len( aNomeLst ) / 2, 0 )
            IF Len( aNomeLst[ nMeio ] ) > 3 .AND. AScan( anNao, nMeio ) == 0
               aNomeLst[ nMeio ] := Left( aNomeLst[ nMeio ], 1 ) + "."
               LOOP
            ENDIF
            FOR nCont = 1 TO nMeio
               DO CASE
               CASE nMeio + nCont < Len( aNomeLst ) .AND. Len( aNomeLst[ nMeio + nCont ] ) > 3 .AND. AScan( anNao, nMeio + nCont ) == 0
                  aNomeLst[ nMeio + nCont ] := Left( aNomeLst[ nMeio + nCont ], 1 ) + "."
                  EXIT
               CASE nMeio - nCont > 1 .AND. Len( aNomeLst[ nMeio - nCont ] ) > 3 .AND. AScan( anNao, nMeio - nCont ) == 0
                  aNomeLst[ nMeio - nCont ] := Left( aNomeLst[ nMeio - nCont ], 1 ) + "."
                  EXIT
               ENDCASE
            NEXT
            nTentativas += 1
            LOOP
         ENDCASE
         EXIT
      ENDDO
   ENDIF
   cAbreviado := Pad( cAbreviado, nTamanho )

   RETURN cAbreviado

Código: Selecionar todos


PEDRO DE ALCANTARA FRANCISCO ANTONIO JOAO CARLOS XAVIER DE PAULA MIGUEL RAFAEL JOAQUIM

PEDRO DE ALCANTARA FRANCISCO ANTONIO JOAO CARLOS XAVIER DE PAULA MIGUEL RAFAEL JOAQUIM
PEDRO DE ALCANTARA FRANCISCO ANTONIO JOAO CARLOS XAVIER DE PAULA MIGUEL RAFAEL JOAQUIM
PEDRO ALCANTARA FRANCISCO ANTONIO JOAO CARLOS XAVIER PAULA MIGUEL RAFAEL JOAQUIM
PEDRO ALCANTARA FRANCISCO ANTONIO JOAO C. XAVIER PAULA MIGUEL RAFAEL JOAQUIM
PEDRO ALCANTARA FRANCISCO ANTONIO JOAO C. X. PAULA MIGUEL RAFAEL JOAQUIM
PEDRO ALCANTARA FRANCISCO ANTONIO J. C. X. P. MIGUEL RAFAEL JOAQUIM
PEDRO ALCANTARA FRANCISCO A. J. C. X. P. MIGUEL RAFAEL JOAQUIM
PEDRO ALCANTARA FRANCISCO A. J. C. X. P. M. RAFAEL JOAQUIM
PEDRO ALCANTARA F. A. J. C. X. P. M. RAFAEL JOAQUIM
PEDRO ALCANTARA F. A. J. C. X. P. M. R. JOAQUIM
PEDRO A. F. A. J. C. X. P. M. R. JOAQUIM
PEDRO A. F. A. J. C. X. P. M. R. JOAQUIM
PEDRO A. F. A. J. C. X. P. M. R. JO
PEDRO A. F. A. J. C. X. P. M.
PEDRO A. F. A. J. C. X. P
PEDRO A. F. A. J. C.
PEDRO A. F. A.
PEDRO A. F
Nota: a cada nome abreviado, testa pra ver se já resolveu, pra não abreviar demais

abreviar nomes

Enviado: 20 Set 2016 02:26
por JoséQuintas
E se o final for FILHO, permanece primeiro e dois últimos, enquanto der.... rs

Código: Selecionar todos


PEDRO DE ALCANTARA FRANCISCO ANTONIO JOAO CARLOS XAVIER DE PAULA MIGUEL RAFAEL JOAQUIM FILHO

PEDRO DE ALCANTARA FRANCISCO ANTONIO JOAO CARLOS XAVIER DE PAULA MIGUEL RAFAEL JOAQUIM FILHO
PEDRO ALCANTARA FRANCISCO ANTONIO JOAO CARLOS XAVIER PAULA MIGUEL RAFAEL JOAQUIM FILHO
PEDRO ALCANTARA FRANCISCO ANTONIO JOAO C. XAVIER PAULA MIGUEL RAFAEL JOAQUIM FILHO
PEDRO ALCANTARA FRANCISCO ANTONIO JOAO C. X. PAULA MIGUEL RAFAEL JOAQUIM FILHO
PEDRO ALCANTARA FRANCISCO ANTONIO J. C. X. P. MIGUEL RAFAEL JOAQUIM FILHO
PEDRO ALCANTARA FRANCISCO A. J. C. X. P. MIGUEL RAFAEL JOAQUIM FILHO
PEDRO ALCANTARA FRANCISCO A. J. C. X. P. M. RAFAEL JOAQUIM FILHO
PEDRO ALCANTARA F. A. J. C. X. P. M. RAFAEL JOAQUIM FILHO
PEDRO ALCANTARA F. A. J. C. X. P. M. R. JOAQUIM FILHO
PEDRO A. F. A. J. C. X. P. M. R. JOAQUIM FILHO
PEDRO A. F. A. J. C. X. P. M. R. JOAQUIM FILH
PEDRO A. F. A. J. C. X. P. M. R. JOAQUIM
PEDRO A. F. A. J. C. X. P. M. R. JO
PEDRO A. F. A. J. C. X. P. M.
PEDRO A. F. A. J. C. X. P
PEDRO A. F. A. J. C.
PEDRO A. F. A.
PEDRO A. F