Actualizar con sql

Soy la de lo arboles, que quiere actualizar dos tablas en un dw.
Probé actualizar la segunda tabla con Sql, pero me sale este error:
Aplication Terminated
Error:Name not found accesing external object property id_campo
at line 20 in clicked cb_2 of w_arbolmed.
O sea hay un problema cuando trato de asignarle a una variable
el valor de la columna pero como no se donde esta mal te mando el código
Esta un poquito largo, pero supongo que esta bien localizado el problema.
boolean lb_commit
string ls_error
integer rc, row
string err
integer li_id_campo, li_id_arbol,li_id_empleado,li_id_rectitud, li_id_ramificacion
integer li_id_calidad, li_id_sanidad
string ls_parcela, ls_observaciones,ls_anio
DECIMAL{2} ld_dap,ld_alt_fuste, ld_alt_tot
//actualizo arbol
rc = dw_1.update()
if rc=-1 then
rollback;
messagebox("Estado", "Grabación incorrecta. No se grabó arbol")
else//si todo esta bien entonces actualizo mediciones
li_id_campo=dw_1.Object.arbol_id_campo[dw_1.GetRow()] ls_parcela=dw_1.Object.arbol_parcela[dw_1.Getrow()]
li_id_arbol=dw_1.Object.arbol_id_arbol[dw_1.Getrow()]
//a partir de aui va la segunda tabla
ls_anio=dw_1.Object.anio_medicion[dw_1.Getrow()] //aqui esta el error//
/*El error podría pensarse que es porque debería escribir mediciones_anio_medicion, pues mediciones es la tabla, pero ya probé eso y el error persiste, Me sabrías decir que me esta faltando?*/
li_id_empleado=dw_1.Object.id_empleado[dw_1.Getrow()]
ld_dap=dw_1.Object.dap[dw_1.Getrow()]
ld_alt_fuste=dw_1.Object.alt_fuste[dw_1.Getrow()]
ld_alt_tot=dw_1.Object.alt_tot[dw_1.Getrow()]
li_id_rectitud=dw_1.Object.id_rectitud[dw_1.Getrow()]
li_id_ramificacion=dw_1.Object.id_ramficacion[dw_1.Getrow()]
li_id_calidad=dw_1.Object.id_calidad[dw_1.Getrow()]
li_id_sanidad=dw_1.Object.id_sanidad[dw_1.Getrow()]
// inserta fila
insert into mediciones(id_campo, parcela, id_arbol, anio, id_empleado,&
dap, alt_fuste, alt_tot, id_rectitud, id_ramificacion, id_calidad, &
id_sanidad, observaciones)
values(:li_id_campo, :ls_parcela, :li_id_arbol, :ls_anio, :li_id_empleado, &
:ld_dap, :ld_alt_fuste,:ld_alt_tot, :li_id_rectitud, :li_id_ramificacion, :li_id_calidad, &
:li_id_sanidad, :ls_observaciones)
using sqlca;
lb_commit = ((sqlca.sqlcode = 0) and (sqlca.sqlcode=0))
If lb_commit then
commit using sqlca;
messagebox("Estado", "Grabacion correcta")
else
ls_error=sqlca.sqlerrtext
rollback using sqlca;
messagebox("error", ls_error)
end if
end if

1 respuesta

Respuesta
1
Estimada colega Marce:
Que bueno saber de nuevo de ti, espero que el proyecto de los arboles este caminando sobre ruedas, con respecto a tu pregunta, el error que me comentas corresponde a la inexistencia de una columna dentro de tu datawindow object.
Mi recomendación es que coloques los nombres de las columnas exactamente igual a las que existen en el datawindow object, aparentemente la columna id_codigo ( que por cierto no la encuentro por ningún lado), no existe dentro de tu datawindow, y es por esto que el error se da.
He analizado tu script, (por cierto veo que estas adoptando la notación húngara), y me he permitido hacer algunas modificaciones, simplemente para que tengas una referencia distinta de como poder manejar los datos con un datawindow. He notado que utilizas el prefijo OBJECT para extreaer la información de los campos de un datawindow, sin embargo personalmente te recomiendo utilices la función GetItemxxx(), esta función tiene variantes, GetItemString(), GetItemNumber(), GetItemDate(), GetItemDateTime(), GetItemDecimal(), y alguno que puede que se me pase por alto, la idea es utilizar estas funciones, retraigan los valores de las columnas en función de la fila indicada. Con esto no quiere decir que tu lo estas haciendo mal, sino que personalmente me inclino más por esta opción, pues el día de mañana puede darte una sorpresa, el hecho de migrar a una nueva version, y algunas cosas ya no se encuentren disponibles, o no funcionen como en la version anterior.
A continuacion el script, revisalo por si tuviera alguna falta de compatibilidad.
BOOLEAN lb_commit
STRING ls_error
STRING ls_parcela
STRING ls_anio
STRING ls_observaciones
INTEGER li_rc
INTEGER li_row
INTEGER li_id_campo
INTEGER li_id_arbol
INTEGER li_id_empleado
INTEGER li_id_rectitud
INTEGER li_id_ramificacion
INTEGER li_id_calidad
INTEGER li_id_sanidad
DECIMAL{2} ldc_dap
DECIMAL{2} ldc_alt_fuste
DECIMAL{2} ldc_alt_tot
lb_commit = (dw_1.AcceptText() = 1)
IF lb_commit THEN
li_row = dw_1.GetRow()
IF (li_row > 0) THEN
li_id_campo = dw_1.GetItemNumber(li_row, 'arbol_id_campo')
ls_parcela = dw_1.GetItemString(li_row, 'arbol_parcela')
li_id_arbol = dw_1.GetItemNumber(li_row, 'arbol_id_arbol')
ls_anio = dw_1.GetItemString(li_row, 'anio_medicion')
li_id_empleado = dw_1.GetItemNumber(li_row, 'id_empleado')
ldc_dap = dw_1.GetItemDecimal(li_row, 'dap')
ldc_alt_fuste = dw_1.GetItemDecimal(li_row, 'alt_fuste')
ldc_alt_tot = dw_1.GetItemDecimal(li_row, 'alt_tot')
li_id_rectitud = dw_1.GetItemNumber(li_row, 'id_rectitud')
li_id_ramificacion = dw_1.GetItemNumber(li_row, 'id_ramificacion')
li_id_calidad = dw_1.GetItemNumber(li_row, 'id_calidad')
li_id_sanidad = dw_1.GetItemNumber(li_row, 'id_sanidad')
lb_commit = (dw_1.Update() = 1)
IF lb_commit THEN
INSERT INTO MEDICIONES(ID_CAMPO,
PARCELA,
ID_ARBOL,
ANIO,
ID_EMPLEADO,
DAP,
ALT_FUSTE,
ALT_TOT,
ID_RECTITUD,
ID_RAMIFICACION,
ID_CALIDAD,
ID_SANIDAD,
OBSERVACIONES)
VALUES( :li_id_campo,
:ls_parcela,
:li_id_arbol,
:ls_anio,
:li_id_empleado,
:ldc_dap,
:ldc_alt_fuste,
:ldc_alt_tot,
:li_id_rectitud,
:li_id_ramificacion,
:li_id_calidad,
:li_id_sanidad,
:ls_observaciones)
USING SQLCA;
lb_commit = ((SQLCA.SQLCode = 0) AND (SQLCA.SQLDBCode = 0))
END IF
IF lb_commit THEN
COMMIT USING SQLCA;
ELSE
ls_error = SQLCA.SQLErrText
ROLLBACK USING SQLCA;
MESSAGEBOX('Estado', 'Grabacion Incorrecta, NO SE GRABO EL ARBOL')
MESSAGEBOX('Error', ls_error)
END IF
END IF
END IF
Explicando:
Como verás, el script contiene cosas como ACCEPTTEXT(), esta función pertenece a el datawindow control, es utilizada para acentar el valor escrito en un campo, por ejem. puede que escribas un valor en un campo del datawindow e inmediatamente con el ratón pinches en el botón grabar, lo que sucedió es que el valor solo quedo pintado en el edit del dw., pero no asentado en la columna, y puede que te encuentres con situaciones sorpresas,
He cambiado el flujo del programa, como veras, primero acceso al numero de la fila seleccionada por medio de la función GETROW()
Igualmente los valores que van a ser grabados en la segunda tabla, los retraigo antes de hacer una actualización en cualquiera de las dos entidades, datawindow o tabla,
He observado que la variable que da valor a la columna OBSERVACIONES no tiene ningún valor, por lo que posiblemente te pueda hacer falta.
Por ultimo un consejo, veo que el anio lo tienes string, mi recomendación es que lo uses numérico, es posible que si intentas ordenar un string no sea exactamente igual que ordenar un numérico, por ejemplo
1
2
3
10
20
30
La lista anterior es tipo numérico, y el orden por medio de un sort, es tal cual.
Sin embargo si esto lo haces con un string puede que quede más o menos así.
1
10
2
20
3
30
Hola!
Gracias por explayarte! Pero, me decís algo sobre id_codigo que no se que es. No creo haberlo escrito.O sea, los campos son todos los que están en el código que escribí. Por ahora probare el código que me recomendaste.
Y ya que estamos y sacaste el tema del campo anio, te cuento que en un principio estaba como numérico, pero luego lo cambié porque en otra pantalla quería hacer consultas por año ingresando el año en un sle o en un em (no lo recuerdo bien ahora y no estoy con mi pc)y para "captarlo" usaba getdata que solo me permite string o date. No me pareció cambiarlo a string, pero no sabía que otra función podía utilizar. ¿Me podrías decir como lo hago con datos numéricos? Ahora soluciné ese problema así, pero más adelante inevitablemente, con otras cuestiones debo saber como poner los datos de un em o de un sle en una variable para hacer búsquedas u operar.
Gracias!
Marce
Con respecto a lo del id_codigo, asumo que el problema esta relacionado con este nombre de campo, simplemente por el mensaje de error que me remites, esta propiedad no es reconocida por el interprete, luego después de compilar en tiempo de ejecución el prefico OBJECT. Es posible que en algún momento te falte completar el nombre de la propiedad por ejemplo se me ocurre que en lugar de haber escrito:
li_id_campo=dw_1.Object.arbol_id_campo[dw_1.GetRow()]
escribiste
i_id_campo=dw_1.Object.id_campo[dw_1.GetRow()]
Esto lo explicaría todo, como ves inmediatamente después del prefijo object existe una propiedad que en este caso en el nombre de una columna, llamada id_campo, es posible que aquí el interprete pb, se refiere en el error que te presenta.
Con respecto a lo del año, en el caso de necesitar ingresar el año, primero como ya te comente anteriormente, te recomiendo utilices un valor numérico, claro esto es casi imposible de hacerlo en un single line edit, pero puedes utilizar entonces el EDITMASK, este control es exactamente igual al SLE, pero contiene la propiedad de colocar una mascara de ingreso, por ejemplo si necesitas ingresar una fecha, puedes optar por:
'[date]' --> lo que significa que tomara el formato de fecha impuesto en el sistema
ó
'dd/mm/yyyy' --> esto indica 2 digitos para el dia, 2 digitos para el mes, y 4 digitos para el año, utilizando este orden dia, mes, año.
Para recuperar el valor exacto, sobre una variable del mismo tipo, tal como en el ejemplo entonces utilizas la función GETDATA(), ej.
DATE ld_fecha
em_1.GetData(ld_fecha)
En el ejemplo anterior, declaro una variable tipo fecha, e integro en la función GetData dicha variable, lo que sucede en esta acción es que el argumento relacionado con la función GetData(), es de tipo reference, lo que significa que tiene 2 vías de acceso, envía el valor inicial a la función, y esta al mismo tiempo deposita un nuevo valor a dicho argumento.
Ademas en tipos de datos como fecha o fecha+tiempo, puedes utilizar funciones como:
DATE('<string>') --> convierte un dato string con formato fecha, a un valor tipo fecha.
YEAR(<fecha>) --> extrae el año de una fecha
MONTH(<fecha>) --> extrae el mes de una fecha
DAY(<fecha>) --> extrae el día de una fecha
TIME('<string>') --> convierte un string con formato HORA, a un valor tipo tiempo.
Igualmente en un stript tipo SQL, puedes utilizar funciones que extraen estos valores.
Por ej.
SELECT num_factura,
nom_cliente,
monto_factura
FROM mae_facturas
WHERE YEAR(fec_factura) = 2003
Esto como veras permite descriminar a todas la tuplas que no correspondan al año 2003.
Si, por ultimo, me fijare de nuevo. Lo que pasa es que ya probe escribiendo mediciones_anio_medicion
mediciones_id_empleado etc,
asi como arbol_id_campo etc y el error no se va.
Finalizare aquí esta consulta porque se hace muy larga. Me fijare otra vez y te cuento.
Gracias
Marce
Hola Agdsys!
Bueno, no se si me estará faltando algún paso, o que,
pero ahora el error que me sale es:
"Invalid datwindow row/column specified at line 31 in clicked
event of object cb_3 of w_modify."
BOOLEAN lb_commit
STRING ls_error
STRING ls_parcela
STRING ls_observaciones
INTEGER li_rc
INTEGER li_row
INTEGER li_id_campo
INTEGER li_id_arbol
INTEGER li_anio
INTEGER li_id_empleado
INTEGER li_id_rectitud
INTEGER li_id_ramificacion
INTEGER li_id_calidad
INTEGER li_id_sanidad
DECIMAL{2} ldc_dap
DECIMAL{2} ldc_alt_fuste
DECIMAL{2} ldc_alt_tot
lb_commit = (dw_1.AcceptText() = 1)
IF lb_commit THEN
li_row = dw_1.GetRow()
IF (li_row > 0) THEN
li_id_campo = dw_1.GetItemNumber(li_row, 'arbol_id_campo')
ls_parcela = dw_1.GetItemString(li_row, 'arbol_parcela')
li_id_arbol = dw_1.GetItemNumber(li_row, 'arbol_id_arbol')
li_anio = dw_1.GetItemNumber(li_row, 'anio_medicion') //el error sigue estando
//aqui cuando empiezo a pasar los campos de la segunda tabla.
li_id_empleado = dw_1.GetItemNumber(li_row, 'id_empleado')
ldc_dap = dw_1.GetItemDecimal(li_row, 'dap')
ldc_alt_fuste = dw_1.GetItemDecimal(li_row, 'alt_fuste')
ldc_alt_tot = dw_1.GetItemDecimal(li_row, 'alt_tot')
li_id_rectitud = dw_1.GetItemNumber(li_row, 'id_rectitud')
li_id_ramificacion = dw_1.GetItemNumber(li_row, 'id_ramificacion')
li_id_calidad = dw_1.GetItemNumber(li_row, 'id_calidad')
li_id_sanidad = dw_1.GetItemNumber(li_row, 'id_sanidad')
lb_commit = (dw_1.Update() = 1)
IF lb_commit THEN
INSERT INTO MEDICIONES(ID_CAMPO,
PARCELA,
ID_ARBOL,
ANIO,
ID_EMPLEADO,
DAP,
ALT_FUSTE,
ALT_TOT,
ID_RECTITUD,
ID_RAMIFICACION,
ID_CALIDAD,
ID_SANIDAD,
OBSERVACIONES)
VALUES( :li_id_campo,
:ls_parcela,
:li_id_arbol,
:li_anio,
:li_id_empleado,
:ldc_dap,
:ldc_alt_fuste,
:ldc_alt_tot,
:li_id_rectitud,
:li_id_ramificacion,
:li_id_calidad,
:li_id_sanidad,
:ls_observaciones)
USING SQLCA;
lb_commit = ((SQLCA.SQLCode = 0) AND (SQLCA.SQLDBCode = 0))
END IF
IF lb_commit THEN
COMMIT USING SQLCA;
ELSE
ls_error = SQLCA.SQLErrText
ROLLBACK USING SQLCA;
MESSAGEBOX('Estado', 'Grabacion Incorrecta, NO SE GRABO EL ARBOL')
MESSAGEBOX('Error', ls_error)
END IF
END IF
END IF
Correcciones
Como ves he cambiado el anio a numero.
Es la segunda tabla
Verifiqué haber escrito bien el nombre de los campos.
El error sigue estando cuando trato de el primer campo de la segunda tabla.
"Jugando", ponía como comentario esta linea y el error simplemente pasaba a la
siguiente linea 32, 33 etc.
El resto es tal cual lo escribiste.
Si puedes ver el error...
Gracias
Marce
Estimada Marce
Estas a un paso de lograrlo, el error es simplemente sencillo, lo que te esta tratando de decir el datawindow es que la columna a la que estas haciendo mención no existe, lo que sucede es que cuando utilizas más de una tabla, la segunda tabla coloca su nombre delanta de cada campo.
El error en la linea 31, 32, 33..., es este mismo por eso es que si comentas una linea el error se traslada a la otra y así hasta que finalicen las menciones a las columnas, por ejemplo, veo que la linea 31, hace mención a la columna id_empleado, por ejemplo esta columna en realidad puede que tenga el nombre de mae_empleados_id_empleado, dentro del datawindow, se me ocurre por ejemplo que pertenece a la tabla llamada mae_empleados, como medida de corrección simplemente abres el datawindow object, te posicionas en la columna que necesitas, y ves cual es el nombre real de esta, en el caso que no la tengas pintada, simplemente en el área de declaración de columnas, allí igualmente conocerás el nombre con la que esta siendo manejada tu columna, esta es una forma peculiar que tiene power builder de manejar las columnas.
saludos afectuosos
agdsys

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas