Ir al contenido


Foto

Obtener sub cadena de una cadena de texto

cadena sub cadena delphi

  • Por favor identifícate para responder
5 respuestas en este tema

#1 tiquinho

tiquinho

    Member

  • Miembros
  • PipPip
  • 36 mensajes

Escrito 26 diciembre 2019 - 11:11

Hola todos

 

Se me ha presentado el siguiente problema:

 

Resulta que se presenta los resultados de varios laboratorios, en algunos casos ponen POSITIVO, positiva, reactiva, NO REACTIVA, etc.

 

Un ejemplo es: La prueba es: positiva

 

Se restringió los valores a los clientes de esta manera:

 

NEGATIVO
NEGATIVA
NO_REACTIVO
NO_REACTIVA
NORMAL
-
 

POSITIVO
POSITIVA
REACTIVO
REACTIVA
ANORMAL
+

 

Aquí les dejo el pedazo de código que haría esto


delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3. vResTexto:string;
  4. begin
  5. vResTexto := AnsiUpperCase(Edit1.Text);
  6.  
  7. if (AnsiContainsText( vResTexto, 'POSITIVO' )) or (AnsiContainsText( vResTexto, 'POSITIVA' )) or (AnsiContainsText( vResTexto, 'REACTIVO' ))or (AnsiContainsText( vResTexto, 'REACTIVA' ))
  8. or (AnsiContainsText( vResTexto, 'ANORMAL' )) or (AnsiContainsText( vResTexto, '+' )) then
  9. ShowMessage('T')
  10. else if (AnsiContainsText( vResTexto, 'NEGATIVO' )) or (AnsiContainsText( vResTexto, 'NEGATIVA' )) or (AnsiContainsText( vResTexto, 'NO_REACTIVO' ))or (AnsiContainsText( vResTexto, 'NO_REACTIVA' ))
  11. or (AnsiContainsText( vResTexto, 'NORMAL' )) or (AnsiContainsText( vResTexto, '-' )) then
  12. ShowMessage('F');
  13. end;

El proceso se realiza bien, pero tengo problemas con REACTIVA y NO_REACTIVA. Ya que si pongo: PRUEBA CON NO_REACTIVA me muestra T y debería de mostrar F.

 

 

Una solución ha sido intercambiar el orden del if. 

 

Pero quisiera saber si existe alguna otra forma de solucionarlos.

 

 

Muchas gracias por la ayuda que me puedan prestar


  • 0

#2 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 26 diciembre 2019 - 07:59

Buenas noches Tiquinho,

Déjame ver si comprendo lo que quieres hacer.

¿Necesitas devolver un valor booleano según el contenido del input restringido a esos valores?

 

¿Cuál es el objetivo tras esto? O, ¿cuál es la idea de porqué buscar evaluar el texto ingresado?

¿Sabes por qué te pregunto esto? Porque noto que lo estás complicando innecesariamente. Si ya tienes la lista de valores posibles, que son conocidos y que incluso se sabe por éstos que "valor" booleano debe regresarse no hace falta ponerse a buscar el texto. Ya tienes la correspondencia hecha:

 

Item - Texto - Valor

1 - NEGATIVO/A - False

2 - NO REACTIVO/A - False

....

6 - ANORMAL - True

 

Sugerencia:

1. En lugar de que el usuario complete y llene a dedo el texto, que seleccione la opción. ¡Sobre todo si como dices, yá está fijado de antemano cuáles van a ser todas las opciones posibles!

2. Que estas opciones ya tengan una correspondencia con el significado/valor esperado. Para este ejemplo incluso puede ser bastante simple:

 

Valor = (IndiceOpcion >= 3)

 

Esa simple línea te dice si es un verdadero o un falso sabiendo el índice de la opción elegida.

 

Si esta lista pudiera ir creciendo y no fuera tan definida podrías tener una tabla en una base de datos que almacene estos items y que se registre la correspondencia item-valor esperado. De hecho el listado que puse yo ya sugiere la estructura mínima de la tabla.

 

3. Tener duplicado el texto por el masculino y el femenino es redundante y para problemas. Ambos son la misma cosa, en lugar ofrece una única alternativa que resume ambos. Usa el o/a que para algo está.

 

¿Se me entiende? La idea es evitarse estar evaluando texto, y en su lugar tener un "listado" de las posiblidades asociado con el valor esperado a devolver. ¿Que pasaría si no controlas lo que escriben en ese TEdit?

 

Saludos,


  • 1

#3 tiquinho

tiquinho

    Member

  • Miembros
  • PipPip
  • 36 mensajes

Escrito 27 diciembre 2019 - 09:17

buenos días Delphius

 

Muchas gracias por la respuesta, y es muy buena idea, pero el problema vas a allá. 

 

No explique muy bien el requerimiento, ya que puse fue un ejemplo y no el contexto del problema.

 

Resulta que existe un modulo de laboratorio donde lo realizo otra persona y yo consumo de lo que esa persona guarda en BD. Resulta que para ciertos laboratorios configuran un campo para que al momento de registrar un laboratorio el resultado lo registren en un varchar. 

 

El laboratorista puede poner por ejemplo:

 

La prueba fue Positiva.

o

La resultado no reactivo

o

hemoglobina: negativa

 

etc, 

 

existen muchas combinaciones.

 

Resulta que existen muchos tipos de configuración de resultados. El 2 guarda T o F, el 3 texto, el 1 es numerico. Para el 1 y 2 no hay problema, el lío es para el tipo 3. 

 

Como es tan amplio los que se puede escribir en un texto. Pedimos al clientes que cuando registrara el resultado de un laboratorio pusiera en el texto alguno de estos valores a riesgo de algún error. 

 

NEGATIVO
NEGATIVA
NO_REACTIVO
NO_REACTIVA
NORMAL
-
 

POSITIVO
POSITIVA
REACTIVO
REACTIVA
ANORMAL
+

 

Las pruebas iban bien, pero con el caso que mencione, al poner NO_REACTIVA tomaba el REACTIVA y no el otro. Pero al cambiar el orden de la condición if el problema se soluciono. Pero no creo que sea lo más optimo.

 

El ejemplo del edit lo puse como para realizar pruebas cortas, y validar las condiciones.

 

Espero haya sido claro y entiendas lo que planteo.

 

Por la respuesta anterior, me sirve para otras cosas que tengo que hacer, muchas gracias.


  • 0

#4 bosoft

bosoft

    Member

  • Miembros
  • PipPip
  • 10 mensajes

Escrito 27 diciembre 2019 - 03:17

Cambia los IFs de orden. Prueba primero los resultados mas largos como NO_REACTIVA y después los mas cortos


php
  1. if (AnsiContainsText( vResTexto, 'NEGATIVO' )) or (AnsiContainsText( vResTexto, 'NEGATIVA' )) or (AnsiContainsText( vResTexto, 'NO_REACTIVO' ))or (AnsiContainsText( vResTexto, 'NO_REACTIVA' ))
  2. or (AnsiContainsText( vResTexto, 'NORMAL' )) or (AnsiContainsText( vResTexto, '-' )) then
  3. ShowMessage('F');
  4. else if (AnsiContainsText( vResTexto, 'POSITIVO' )) or (AnsiContainsText( vResTexto, 'POSITIVA' )) or (AnsiContainsText( vResTexto, 'REACTIVO' ))or (AnsiContainsText( vResTexto, 'REACTIVA' ))
  5. or (AnsiContainsText( vResTexto, 'ANORMAL' )) or (AnsiContainsText( vResTexto, '+' )) then
  6. ShowMessage('T');

Saludos


  • 1

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 27 diciembre 2019 - 07:17

Si la busqueda indexada no es opción, y debes buscar el texto, aún podemos aprovechar el enfoque de la lista/tabla que te sugerí.

En lugar de tener una compleja evaluación llena de ors que pudiera en el futuro crecer y volverse por demás compleja yo te sugiero tener esta tabla/lista e iterar sobre esta para consultar.

 

algo como un:


delphi
  1. find := false;
  2. i := 0;
  3.  
  4. while (i <= lista.count) or (NOT find) do
  5. begin
  6. find := AnsiContainsText(TextSearch, lista[i].text);
  7. i := i + 1;
  8. end;
  9.  
  10. if (find)
  11. then result := lista[i - 1].test
  12. else result := false;

Lista no es más que el contenido de la tercia {index, text, test} =  {item, nombre, valor} que te describí antes.

Viendo el código de ejemplo anterior, la idea es buscar cada item de la lista en el texto sobre el cual buscar, y en caso de la coincidencia se devuelve el valor que corresponde al caso. Si no hay coincidencia se devuelve un false.

 

Y como bien menciona bosoft debes evaluar primero las cadenas más largas que la cortas.

 

Espero que se entienda la idea.

 

Saludos,


  • 1

#6 tiquinho

tiquinho

    Member

  • Miembros
  • PipPip
  • 36 mensajes

Escrito 08 enero 2020 - 08:44

Gracias Delphius y Bosoft por sus respuesta.

 

Con la propuesta de Bosoft lo solucione.

 

La propuesta de Delphius me parece muy interesante y muy acertada, la voy a implementar para la siguiente versión del ejecutable, la pienso realizar con calma. 

 

Gracias por la ayuda prestada y por las soluciones propuestas.


  • 1





Etiquetado también con una o más de estas palabras: cadena, sub cadena, delphi

IP.Board spam blocked by CleanTalk.