PDA

Ver la Versión Completa : Convertir valores int de un campo a varchar


davidmedina29
19-02-2016, 16:17:05
Buen dia compañeros de nuevo con un detalle.

tengo una base de datos llamada RH_PERIODOS_SEM en sqlserver con los campos: PERIODOS, MES, EJERCICIO

el problema es que el campo MES esta en data type: Int y registra los numeros del mes del 1 al 12 y hay dos detalles..

quiero que en cxGrid que tengo en ves de que se vea el numero del MES(1-12) que se vea el nombre del mes por ejemplo asi se ve:
MES
2
4
11

y quiero que se vea asi
MES
Febrero
Aril
Noviembre

y hice un combobox con los 12 meses pero puse los items con nombre.. Enero, Febrero, Marzo etc.. como puedo guardarlos en la tabla si los valores son int

ayuda porfavor !!

Casimiro Notevi
19-02-2016, 17:13:43
y quiero que se vea asi
MES
Febrero
Aril
Noviembre

y hice un combobox con los 12 meses pero puse los items con nombre.. Enero, Febrero, Marzo etc.. como puedo guardarlos en la tabla si los valores son int

Obviamente, no se puede, salvo que guardes "1", "2", "3", ...

AgustinOrtu
19-02-2016, 17:45:38
La forma de manejar esto es usar funciones de conversion


function MesAInt(const TextMes: strnig): Integer;
function IntAMes(const IntMes: Integer): string;


Dependiendo de la version de Delphi, la mejor forma de hacerlo es combinando un tipo enumerado con su correspondiente helper

Te permite implementar algo como esto:


var
AMonth: TMonth;
I: Integer;
Text: string;
begin
AMonth := TMonth.Enero;
ShowMessage(AMonth.ToStr); // imprime Enero en pantalla
AMonth := AMonth.Next; // AMonth = TMonth.Febrero;

I := AMonth.ToInt; // I = 2

Text := 'Julio';
AMonth := TMonth.Parse(Text); // AMonth = TMonth.Julio

Text := TMonth.ParseInt(12).ToStr; // TMonth.ParseInt(12) = TMonth.Diciembre -> ToStr = 'Diciembre'
end;

davidmedina29
19-02-2016, 18:32:45
Gracias por tu aporte agustin, lo implemente y tuve otros problemas

decidi cambiar el data type a varchar y cambiar los valores manualmente

les agradesco sus comentarios ;):D:)

bitbow
19-02-2016, 20:01:06
Hola davidmedina29, en algún momento me toco hacer algo similar, te comento como se resolvio.

Para los meses >> Genere un Array con los meses y acceder mediante la posicion del 1 al 12.
Para guardar el dato >> Mencionas un combobox, puedes guardar el indice de este.

Para mostrar el nombre del mes en lugar de numero puedes usar los eventos del dataset y cambiarlos con le array previo.

Saludos.

davidmedina29
19-02-2016, 20:10:53
hola bitbow gracias por responder

me podrias dar un ejemplo porque no se me ocurre como hacer el array mas bien no estoy familiarizado con ellos

te lo agradeceria mucho!!

AgustinOrtu
19-02-2016, 21:21:09
Gracias por tu aporte agustin, lo implemente y tuve otros problemas

decidi cambiar el data type a varchar y cambiar los valores manualmente

les agradesco sus comentarios ;):D:)


Que problemas? Como lo implementaste?

Si tenes la posibilidad de usar record helpers te aconsejo que no la dejes pasar; te permiten escribir codigo altamente legible :)

A ver, es mucho mas agradable leer:


ShowMessage(Enumerativo.ToStr);


Que esto:


ShowMessage(EnumerativoToStr(Enumerativo));


Un lugar interesante para obtener ideas de implementacion es en la unidad System.SysUtils, en donde se definen distintos tipos de record helpers para tipos como string, Integer, etc

davidmedina29
19-02-2016, 23:45:27
El detalle es que habia cambiado de int a varchar en el campo MES y cambie todo manualmente

pero no pude acomodarlos con el order by me aparecen alfabeticamente:
Abril
Agosto
Diciembre
etc..

y los quiero acomodados en orden deacuerdo al calendario
Enero
Febrero
Marzo
etc..

AgustinOrtu
20-02-2016, 01:11:40
A mi me parece una buena idea almacenar los meses como un valor numerico

En realidad, cuando armo una BD, de todas las opciones los tipos string son "casi siempre", la peor; si puedo poner otra cosa, mejor

El pro mas importante de los tipos numericos es que son extremadamente rápidos, para realizar busquedas, filtros y ordenamiento de tablas son muchisimo mas eficientes

Luego cuando se quiere presentar al usuario el valor "real", es decir, para un usuario quiza no le haga mucha gracia ver el numero 3 en lugar de "Marzo", pero es bastante "economico" realizar un par de conversiones desde el valor 3 a Marzo

Pero al fin y al cabo es como que de este paso no podes escapar porque siempre terminas aplicando algun formato a cualquier campo (fechas, importes monetarios, horas, etc) asi que podria considerarse como una de las operaciones mas de "formato"



Ahora, si hay que ordenar una tabla con millones de registros, en donde el valor a comparar son todos strings, madre mia :)

ecfisa
20-02-2016, 08:38:24
Hola David.
Buen dia compañeros de nuevo con un detalle.

tengo una base de datos llamada RH_PERIODOS_SEM en sqlserver con los campos: PERIODOS, MES, EJERCICIO

el problema es que el campo MES esta en data type: Int y registra los numeros del mes del 1 al 12 y hay dos detalles..

quiero que en cxGrid que tengo en ves de que se vea el numero del MES(1-12) que se vea el nombre del mes por ejemplo asi se ve:
MES
2
4
11

y quiero que se vea asi
MES
Febrero
Aril
Noviembre

Otra opción, es traer el nombre directamente desde la consulta SQL:

SELECT PERIODOS,
(CASE MES
WHEN 1 THEN 'ENERO'
WHEN 2 THEN 'FEBRERO'
WHEN 3 THEN 'MARZO'
WHEN 4 THEN 'ABRIL'
...
WHEN 12 THEN 'DICIEMBRE' END) AS MES
EJERCICIO,
...
FROM RH_PERIODOS_SEM
...



...
y hice un combobox con los 12 meses pero puse los items con nombre.. Enero, Febrero, Marzo etc.. como puedo guardarlos en la tabla si los valores son int

ayuda porfavor !!
Este es otro tema, pero coincido con bitbow que podes tomar el número del mes seleccionado del índice del combo:

...
if ComboBox1.ItemIndex <> -1 then
tuDataSet.FieldByName('MES').Value := ComboBox1.ItemIndex + 1; // (1er índice = 0)
...


Saludos :)

davidmedina29
22-02-2016, 16:13:32
hola ecfisa gracias por aporte me sirvio!!

cambie en data type a varchar y funciono me mostro los meses con nombre pero el detalle es que no debo de cambiarlos el date type lo tengo que dejar en int.

tengo un query.. Select Periodo, Ejercicio, Mes, from RH_PERIODOS_SEM.

mi duda donde podria poner esa consulta en mi codigo delphi para que funcione

gracias!

davidmedina29
22-02-2016, 19:27:05
buenas tardes tengo un cxcombobox que tiene los meses de enero a diciembre

lo que quiero es que cuando guarde me lo guarde en numero del 1 al 12 segun el mes
alguna sugerencia?:(

roman
22-02-2016, 19:31:22
Aunque cxcombobox no es un control estándar de delphi, debe ser similar a un combobox, el cuál tiene una propiedad ItemIndex que indica el índice del elemento seleccionado. Este índice es el que tendrías que guardar (0 - enero, 1 - febrero, 2 - marzo, etc.) Si lo quieres basado en 1, sólo tienes que sumar 1 a ItemIndex.

LineComment Saludos

AgustinOrtu
22-02-2016, 19:42:00
Otra vez repitiendo (http://www.clubdelphi.com/foros/showthread.php?t=89863) hilos??

La respuesta de ecfisa (http://www.clubdelphi.com/foros/showpost.php?p=502379&postcount=10) te debería servir perfectamente

Casimiro Notevi
22-02-2016, 19:58:47
buenas tardes Buenas tardes, y deja de repetir hilos, gracias :rolleyes:

davidmedina29
23-02-2016, 19:00:08
buen dia compañeros, pues le e buscado y no e encontrado la solucion ya proble con lo que me compartio ecfisa lo plantie asi:


procedure TfPeriodosNominaNvo.cxComboBox2PropertiesChange(Sender: TObject);
var
ID: Integer;
begin
if cxComboBox2.ItemIndex <> -1 then
MSQuery1.FieldByName('MES').Value := cxComboBox2.ItemIndex +1;
end;


y nada me digue marcando este error

'05 mayo' is not a valid integer value for field 'MES'


mi cxcomboboox tiene los siguientes items:
01 Enero
02 Febrero
03 Marzo
04 Abril
05 Mayo
06 Junio
07 Julio
08 Agosto
09 Septiembre
10 Octubre
11 Noviembre
12 Diciembre

aqui les dejo tmbien la interfaz del sistema con el error:
3320

cualquier aporte se los agradeceria compañeros.. saludos.

davidmedina29
23-02-2016, 19:03:26
la variable :


ID: Integer;


es de otro ejemplo que tenia ahi pero no me funciono se me paso quitarla.

AgustinOrtu
23-02-2016, 20:12:08
La excepcion se produce en el evento cxComboBox2PropertiesChange o en otro lado?

davidmedina29
23-02-2016, 20:15:25
Hola AgustinOrtu
no tengo alguna excepcion solo el codigo que puse arriba lo tengo en el evento propertiesChange

saludos

AgustinOrtu
23-02-2016, 20:21:13
Solamente podemos adivinar

Ese error no te puede aparecer en ese evento, ya que seria una contradicción


if cxComboBox2.ItemIndex <> -1 then
...


Con esa linea se puede deducir que cxComboBox2.ItemIndex es un ordinal, presuntamente de tipo Integer; si fuera string Delphi no te dejaria compararlo contra -1. Y recordemos que Delphi es fuertemente tipificado

Por lo tanto, si la siguiente linea dice:


MSQuery1.FieldByName('MES').Value := cxComboBox2.ItemIndex +1;


Estas asignando un Ordinal (Integer, Word, Byte, etc) al campo MES

Por lo tanto es imposible que salga un error:


'05 mayo' is not a valid integer value for field 'MES'


Yo creo que hay algo que te falta mostrarnos.

No tendras algun codigo que asigne valores a los campos y luego haga Post?
No estaras usando algun componente Query/Command para enviar un Insert o Update?
No tendras conectado componentes mediante propiedades DataSource?

davidmedina29
23-02-2016, 20:30:16
ok lo que pasa es que mi base de datos guarda en el campo MES solamente INT osea del 1 al 12

en el combobox tengo los meses de enero a diciembre y cuando los quiero guardar pues obiamente me marca ese error ya que la base de datos espera valores de tipo int y no string

intente poniendo el aporte del compañero ecfisa pero no soluciono el error que me seguia apareciendo

procedure TfPeriodosNominaNvo.cxComboBox2PropertiesChange(Sender: TObject);
begin
if cxComboBox2.ItemIndex <> -1 then
MSQuery1.FieldByName('MES').Value := cxComboBox2.ItemIndex +1;
end;


lo que en si quiero es que no me guarde el texto del combobox si no el entero osea, si selecciono 'Enero' que me guarde el '1', si selecciono 'Abril' que me guarde el '4' .. etc

te comparto mi boton guardar.

procedure TfPeriodosNominaNvo.cxButton1Click(Sender: TObject);
begin
if cxComboBox2.Text='' then
MessageDlg('Falta Ingrsar el Mes', mtError, [mbOK], 0)
else
begin
if DM.Q_PerNomina.State=dsInsert then
begin
DM.Q_PerNomina.FieldByName('PERIODO').AsString := cxTextEdit1.Text;
DM.Q_PerNomina.FieldByName('MES').AsString := cxComboBox2.Text;
DM.Q_PerNomina.FieldByName('EJERCICIO').AsString := cxComboBox1.Text;
DM.Q_PerNomina.Post;
application.MessageBox('Datos Guardados Con Exito','Informacion',MB_OK);
//MessageDlg('Dato Guardado', mtInformation, [mbOK], 0);
fPeriodosNominaNvo.Close;
end
else
begin
if DM.Q_PerNomina.State=dsEdit then
DM.Q_PerNomina.FieldByName('PERIODO').AsString := cxTextEdit1.Text;
DM.Q_PerNomina.FieldByName('MES').AsString := cxComboBox2.Text;
DM.Q_PerNomina.FieldByName('EJERCICIO').AsString := cxComboBox1.Text;
DM.Q_PerNomina.Post;
application.MessageBox('Datos Modificados Con Exito','Informacion',MB_OK);
//MessageDlg('Ingreso Guardado', mtInformation, [mbOK], 0);
fPeriodosNominaNvo.Close;
end
end
end;

roman
23-02-2016, 20:40:50
Te estás haciendo líos tú sólo. Ya Agustín lo explicó muy bien: es imposible ese mensaje de error con el código que ponías. Ese mensaje sale por el código que ahora pones, que es distinto. Así que, las líneas:


DM.Q_PerNomina.FieldByName('MES').AsString := cxComboBox2.Text;


cámbialas por


DM.Q_PerNomina.FieldByName('MES').AsInteger := cxComboBox2.ItemIndex + 1;


LineComment Saludos

roman
23-02-2016, 20:49:59
Por otro lado, si la única diferencia entre el insert y el update es el texto del mensaje, no vale la pena distinguir los dos casos. Déjalo así:


procedure TfPeriodosNominaNvo.cxButton1Click(Sender: TObject);
begin
if cxComboBox2.Text='' then
MessageDlg('Falta Ingrsar el Mes', mtError, [mbOK], 0)
else if (DM.Q_PerNomina.Statein [dsInsert, dsEdit] then
begin
DM.Q_PerNomina.FieldByName('PERIODO').AsString := cxTextEdit1.Text;
DM.Q_PerNomina.FieldByName('MES').AsInteger := cxComboBox2.ItemIndex + 1;
DM.Q_PerNomina.FieldByName('EJERCICIO').AsString := cxComboBox1.Text;
DM.Q_PerNomina.Post;
Application.MessageBox('Datos Guardados Con Exito','Informacion',MB_OK);
fPeriodosNominaNvo.Close;
end
end;


LineComment Saludos