Hola Pedro,
Pedro escribió:
Hola Ariel,
Gracias por la ayuda con listas desplegables, no tuve problemas al
ajustarlas al documento.
necesito seleccionar de una lista desplegable un elemento
que me entregará un valor en un campo numérico de un formulario en el
documento .odt, ya probé con la rutina:
Sub ActualizaForm(oEvent)
Dim oModelo, oForm
Dim sCampo$, iItemSeleccionado%, sValorSelecc$, sFiltro$
oModelo = oEvent.Source.Model
sCampo = oModelo.DataField
iItemSeleccionado = oModelo.SelectedItems(0)
sValorSelecc = oModelo.ValueItemList(iItemSeleccionado)
oForm = oModelo.Parent
sFiltro = sCampo + "=" + sValorSelecc
REM tildar lo siguiente si NO se desea actualizar el registro con los
datos del formulario
oForm.updateRow()
oForm.Filter = sFiltro
oForm.ApplyFilter = True
oForm.reload()
End Sub
Al ejecutar esta rutina, el mensaje que aparece dice "Tipo de datos o
valor inadmisible. Índice fuera del área definida".
Para saber bien en qué línea se produce el error, te aconsejo que
incluyas en todas tus rutinas un manejo de error, con un mensaje de
error indicando la línea (busca en la Ayuda de OOo Basic Err y Error).
Si no, no puedo saber dónde se produce exactamente. Así que lo que sigue
puede no ser que resuelva tu problema (de todas formas seguramente será
útil -- ...espero ).
Veamos si es lo siguiente: seguramente has copiado el código de alguno
de mis ejemplos ... mea culpa [1], el empleo de updateRow() es bastante
peligroso, por lo menos así solo como está: updateRow() lo que hace es
actualizar la respectiva fila de la base de datos con el contenido del
formulario, pero no puede emplearse siempre:
http://api.openoffice.org/docs/common/ref/com/sun/star/sdbc/XResultSetUpdate.html#updateRow
"updates the underlying database with the new contents of the current
row. *Cannot* be called when on the insert row."
En varias ocasiones es necesario actualizar la fila actual: si estás por
filtrar el formulario de acuerdo a lo seleccionado en la lista, es
posible que el contenido actual del formulario haya sido modificado, y
si aplicas el filtro, esos cambios NO se guardan, debes guardarlos tú.
Para ello sirve updateRow().
Pero prueba con mover todo el formulario para insertar un nuevo
registro, luego intenta aplicar updateRow(): te genera un error pues
updateRow() "*Cannot* be called when on the insert row"
Lo más elegante y *seguro* para solucionar todo esto es emplear la nueva
interfaz XFormOperations:
http://api.openoffice.org/docs/common/ref/com/sun/star/form/runtime/XFormOperations.html
Te recomiendo que leas la "Description".
Un work-around si no deseas emplear esa nueva interfaz, es verificar el
estado del formulario antes de invocar updateRow()
oForm = oEvent.Source.Model.Parent
If oForm.AllowUpdates AND oForm.IsModified AND NOT oForm.IsNew Then
oForm.updateRow()
End If
AllowUpdates indica si el formulario acepta modificaciones. Nota que
esto no quiere decir SI tienes privilegios INSERT sobre la base de
datos, sino sólo si el formulario está configurado para ingresar datos.
Si retorna FALSE, mediante la API igual puedes insertar datos, siempre
que la base de datos te lo permita. Para averiguar esto debes emplear
otros métodos (no los explico porque suponemos que trabajas con una base
HSQLDB embebida y no hay problemas de privilegios de usuario).
http://api.openoffice.org/docs/common/ref/com/sun/star/form/component/DataForm.html#AllowUpdates
IsModified indica que la fila actual ha sido modificada
http://api.openoffice.org/docs/common/ref/com/sun/star/sdb/RowSet.html#IsModified
IsNew indica si el RowSet está posicionado en un registro nuevo
http://api.openoffice.org/docs/common/ref/com/sun/star/sdb/RowSet.html#IsNew
Empleo NOT IsNew porque si IsNew es TRUE, no puedes emplear updateRow(),
sino insertRow(). *PERO* para emplear insertRow() debes tener en cuanta
un montón de cosas, tal como lo explica la descripción de XFormOperations.
Pongamos un ejemplo: el formulario está en posición para insertar un
nuevo registro, sólo has ingresado algunos datos en algunos campos, si
aplicas insertRow() antes de filtrar el formulario para que no se
pierdan esos datos nuevos pueden pasar dos cosas no deseadas:
* guardar un registro donde NO todos los campos han sido llenados
* producir un ERROR si algún campo no llenado es un campo obligatorio
(p.e. una llave primaria) o si viola la integridad referencial de la
base de datos.
Por esto, lo más seguro es emplear XFormOperations.
Si quisieras emplear los métodos antiguos deberías hacer algo así:
oForm = oEvent.Source.Model.Parent
'esto para no perder los datos ingresados en un registro existente
If oForm.AllowUpdates AND oForm.IsModified AND NOT oForm.IsNew Then
oForm.updateRow()
'esto para no perder los datos en un registro nuevo
ElseIf oForm.IsNew Then
'acá hacer un MONTÓN de trabajo: chequear cada control del formulario,
ver si su contenido ha sido enviado al formulario y/o a la base de
datos, etc.....
End If
Nuevamente te sugiero que leas la descripción de XFOrmOperations.
Una salida no muy elegante es mostrar un mensaje al usuario si
IsNew=TRUE: como por ejemplo "Antes de filtrar el formulario mediante lo
seleccionado en la lista, guarda los datos del registro actual o se
perderán...etc..."
PS: El colistero Oscar Darío Perdiguero, manifestó un pequeño reclamo
por incluir al grupo en CC en mis mensajes. Sólo seguiré tus
instrucciones, por lo que, en esta oportunidad no enviaré este correo al
grupo.
Te recomiendo que incluyas mi dirección en el "Para", o simplemente lo
envíes a la lista de correo: yo recibo todos los mensajes de la lista.
Si esta consulta es indicada para la lista de usuarios, es algo
debatible. Yo opino que sí: si bien son cuestiones de programación, el
tema es general y a nivel de un usuario básico; para manejar OOo Base
sacándole todo el jugo es necesario incluir algunas macros.
No hay lista apropiada para este tipo de temas (pues dev@ es para temas
de traducción -- o teóricamente para temas de "desarrollo", pero este
tema no es de "desarrollo" sino de cómo emplear macros en un nivel
básico y para las necesidades general de un usuario promedio, NO
desarrollar algo profesionalmente).
Los motivos por los cuales sugiero (aunque casi siempre sin éxito) a
todas personas que me consultan que envíen sus consultas directamente a
la lista y no a mí solamente son:
* la respuesta puede ser útil para otros usuarios, no sólo ahora sino
luego cuando busquen por internet o en el archivo de la lista (yo mismo,
antes de enviar una consulta a alguna lista, antes busco en las bases de
datos, y suelo encontrar la solución ahí, ahorrando tiempo a otras
personas en leer un mensaje que ya ha sido solucionado antes)
* otros usuarios pueden participar y colaborar aportando su punto de
vista, e incluso una solución (pues no soy el amo de la verdad y puedo
[suelo] estar equivocado)
* si la respuesta es pública, ahorro tiempo luego si alguien me consulta
lo mismo: esta respuesta me ha llevado casi una hora (entre buscar las
referencias, chequear el código, etc.), la próxima vez que alguien me
consulte lo mismo, puedo directte. remitirlo a la base de datos de la lista.
* por último, cuando algún amante de la meritocracia esté interesado en
saber qué hago, no necesito enviarle mi curriculum vitae o pedir a todos
aquellos a quienes he ayudado desinteresadamente que le envíen sus mails
Saludos,
Ariel
[1] ya he prometido a varios usuarios actualizar la base de ejemplo...
pero nunca me tomo el tiempo para hacerlo. Trataré de que no pase de
esta semana ;-)
--
Ariel Constenla-Haile
La Plata, Argentina
[EMAIL PROTECTED]
[EMAIL PROTECTED]
http://www.arielconstenlahaile.com.ar/ooo/
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]