Hola Pedro,

Pedro escribió:
Hola Ariel,

Efectivamente, las variables están declaradas como Object (campo
numérico) porque es un control de un formulario (como lo describes en tu
correo).

AHhhhhhhhhhhhhhhhhhhhhhh!!!! == eso significa: ahí está el error.

Dim oModeloControl as Object
oModeloControl = oMiFormulario.getByName("nombre_control")

Cuando accedes por nombre a un elemento del formulario, estás accediendo al *MODELO* del control, *NO* al valor que hay en el control.

Esto quiere decir, no puedes transformar esa variable de objeto con alguna función, para obtener el valor respectivo:

Dim sValor as String
sValor = CStr(oModeloControl)

Dim dValor as Double
dValor = CDbl(oModeloControl)

EL modelo del control es un conjunto de propiedades, a las cuales accedes mediante getPropertyValue("NombrePropiedad"). En OOo Basic no es necesario emplear ese método, sino directte. el punto como operador:

aValor = oModeloControl.NombrePropiedad


Como dije al final del mensaje anterior, el tipo de propiedades que posee el modelo de un control depende del tipo de control.


Además si accedes al control, en vez de a su modelo, puedes emplear los métodos de las interfaces que implementa ese control.

Al control accedes casi siempre que asignas una macro a un evento, mediante la variable de objeto oEv[ent]:

oControl = oEv.Source
oModeloControl = oEv.Source.Model




Estuve indagando en la Red y he encontrado una solución a la
problemática del separador decimal en SQL, bien, en mi base de datos
ahora estoy aplicando:

...
        sCcInt = oCalculosForm.getByName("TbmpInt")                   'cc 
interior
planta

¿sCcInt es una variable definida como String?
En este caso getByName() devuelve un *objeto* = el MODELO del control

        sCcExt = oCalculosForm.getByName("TbmpExt")                   'cc 
exterior
planta

  dim strNum1, strNum2 as string
  dim sngNum1, sngNum2 as single

al declarar así, en OOo Basic, sólo estás declarando el tipo de la última variable: las dos primeras quedaron sin declarar, el tipo al final de la línea NO se aplica a todas las variables de la misma, cada una debe tener su tipo indicado:

     dim strNum1 as string, strNum2 as string
     dim sngNum1 as single, sngNum2 as single

Single no es la mejor opción, porque la propiedad Value tiene un valor double


        sngNum1 = sCcInt.Value
        sngNum2 = sCcExt.Value

Esto es precisamente lo que te indicaba en la nota 1 del mensaje anterior: si accedes al modelo (que es un objeto), debes obtener el valor de su propiedades. En el caso de un campo numérico:


>> * UnoControlNumericField/UnoControlNumericFieldModel

esto es el control:

>> ** UnoControlNumericField

que implementa estas dos interfaces con sus respectivos métodos:

>>       XTextComponent::getText()               retorna una cadena
>>       XNumericField::getValue()               retorna double

esto es el modelo:

>> ** UnoControlNumericFieldModel

que tiene la siguiente propiedad:

>>       UnoControlNumericFieldModel::Value      retorna double


Esto significa que debes aprender las propiedades de un servicio y los métodos de las interfaces implementadas.

Todo esto lo "comprenderás" leyendo la referencia de la API. Para marearte un poco, el ejemplo de un campo numérico en un formulario ligado a una base de datos:

* el servicio com.sun.star.form.component.DatabaseNumericField
http://api.openoffice.org/docs/common/ref/com/sun/star/form/component/DatabaseNumericField.html
especifica un campo numérico en un formulario ligado a una base de datos
EN la página verás que no tiene propiedades propias, pues hereda las de los servicios que incluye

incluye a

** com.sun.star.form.DataAwareControlModel
http://api.openoffice.org/docs/common/ref/com/sun/star/form/DataAwareControlModel.html


** com.sun.star.form.component.NumericField
http://api.openoffice.org/docs/common/ref/com/sun/star/form/component/NumericField.html


este último incluye a su vez los servicos:

***  com.sun.star.awt.UnoControlNumericFieldModel
http://api.openoffice.org/docs/common/ref/com/sun/star/awt/UnoControlNumericFieldModel.html

***  com.sun.star.form.FormControlModel
http://api.openoffice.org/docs/common/ref/com/sun/star/form/FormControlModel.html


Para saber TODAS las propiedades de un campo de control numérico perteneciente a un formulario de una base de datos, debes buscar en el servicio com.sun.star.form.component.DatabaseNumericField y *TODOS* los demás que incluye.


Más fácil: emplea XRay sobre el objeto

http://es.openoffice.org/files/documents/73/3981/XrayTool_es.odt

oModelo = oForm.getByName("nombre")
oModelo = oEv.Source.Model
oControl = oEv.Source

luego

xray oModelo
xray oControl

para ver todas las propiedades, métodos, servicios, interfaces de un objeto.

¿Conocías XRay? Puedo asegurar que empleando Xray hubieras solucionado el problema al instante.

Tal vez cueste entenderlo al principio, pero el poco tiempo de estudio que requiere te salvará horas de andar buscando una solución a algo tan simple como que el método getByName(), aplicado a un formulario, retorna un *objeto* que es el *modelo* del control, y para acceder al *valor* que hay en él, debes acceder a alguna *propiedad* de ese modelo, no transformar el objeto en algo más (String, Double, etc.)


Espero que ayude :-)

Ariel.


El sáb, 01-12-2007 a las 23:23 -0300, Ariel Constenla-Haile escribió:

Hola Pedro, hola gente,

Pedro escribió:
Hola Ariel,

Retomando el tema pendiente en mi base de datos, referente a INSERT
INTO. Estoy usando la configuración local como separador decimal, es
decir la coma  " , ", efectivamente SQL únicamente permite usar el
punto. Ahora, mi problema es que necesito ingresar esta variable a la
nueva tabla, esta variable está declarada como Object en el formulario.
¿por qué la declaras como Object? ¿la obtienes de algún control del formulario, p.e. miVar = oMiForm.getByName("control_xxx")?

INSERT INTO Sólo me permite almacenar la variable como texto al
convertirla con CStr, respetando los decimales, pero una vez en la
tabla, no puedo realizar operación matemática con ese campo. Entonces,
las preguntas son:

1.- ¿Cómo puedo almacenar la variable como número en la tabla sin tener
que cambiar la configuración del sistema?
Mira si los ejemplos en

http://www.arielconstenlahaile.com.ar/ooo/temp/INSERT_INTO.odb

responden tu pregunta.
Es posible teniendo en cuenta todos los aspectos involucrados:
1. cómo obtienes el dato que deseas guardar [ver NOTA 1]
2. en qué tipo de variable lo almacenas
3. en qué tipo de campo lo deseas guardar
4. qué instrucción SQL empleas para insertar los datos en la tabla


Supongamos que estamos trabajando con la siguiente tabla HSQLDB:


CREATE CACHED TABLE "TEST_DECIMAL_SEP"(
          "id"        INTEGER
                      GENERATED BY DEFAULT AS IDENTITY
                      (START WITH 0)
                      NOT NULL
                      PRIMARY KEY,
          "field1"    DECIMAL(15,5),
          "field2"    DECIMAL(15,5),
          "field3"    DECIMAL(15,5),
          "field4"    DECIMAL(15,5)
);

La instrucción SQL que deseamos ejecutar empleando OOo Basic es:

     sSQL =  "INSERT INTO ""TEST_DECIMAL_SEP"" VALUES ("     &_
                 "NULL ,"     &_
                 "1234567890.12345,"     &_
                 "CAST( '43210.123' AS DECIMAL ),"    &_
                 CDbl("6543,0123")  &   ","    &_
                 CDbl("6543.0123")  &   ")"

todas esas expresiones se transforman automáticamente, por el simple hecho de concatenarlas mediante el operador &, en la siguiente cadena:

"INSERT INTO "TEST_DECIMAL_SEP" VALUES (NULL ,1234567890.12345,CAST(
'43210.123' AS DECIMAL ),6543,0123,65430123)"


Al ejecutar esta instrucción SQL, genera el siguiente error:

"Se ha producido una excepción
Type: com.sun.star.sdbc.SQLExceptionMessage:
*Column* *count* does *not* match in statement [INSERT INTO "TEST_DECIMAL_SEP"
VALUES (NULL ,1234567890.12345,CAST( '43210.123' AS DECIMAL ),6543,0123,]."

La causa de ese error:

CDbl("6543,0123")  convierte la cadena "6543,0123" en un valor tipo
Double, PERO al concatenar el valor de retorno en la cadena sSQL estamos
implícitamente transformándolo a cadena, siendo equivalente a
CStr(CDbl("6543,0123") ), lo cual, en CASTELLANO, retorna una cadena con
una coma en el separador decimal:  "6543,0123".

Al ejecutar la instrucción SQL, en "6543,0123" la coma NO es
interpretada como separador decimal, sino como indicando que se trata de
DOS VALORES DISTINTOS:  6543 y 0123; por lo tanto hay una columna de más
en la instrucción INSERT.

El problema es que estamos transformando una cadena a un Double
(CDbl("6543,0123") ), pero luego al concatenar este valor Double en la
cadena sSQL lo volvemos a transformar en una cadena, transformación
dependiente de la config. *regional* del sistema.

La solución NO es transformar en Double una cadena con punto como
separador decimal, porque en la config. de idioma castellano
CDbl("6543.0123") se convierte en un entero 65430123.


Solución:

1. Eliminar el indicador de MILES
2. Reemplazar la COMA del separador decimal por el PUNTO.

Function formatNumber(aNumber) as String
     On Error Resume Next
     Dim aTemp, sReturn
     'si el valor se obtiene como una cadena
     'de un campo formateado tipo 1.234,56
     'quitar primero el indicador de MILES
     aTemp = CDbl(aNumber)
     'cambiar el separador decimal
     sReturn = Join( Split(aTemp,","), ".")
     formatNumber() = sReturn
End Function

Esta solución sigue siendo dependiente de la configuración local: si la
config. local es castellano y se intenta pasar un número con formato
inglés como
         1,234,567.012

CDbl(aNumber) generaría un error, como lo explica la Ayuda para esa
función de OpenOffice.org Basic:

"Para convertir una expresión de cadena, el número debe introducirse
como texto normal ("123,5") usando el formato numérico predeterminado
del sistema operativo."


2.- Si es almacenada como texto en la tabla, ¿hay alguna forma de
convertirla a número en una consulta?
se puede emplear la función de HSQLDB *CAST*

Es posible insertar un literal tipo cadena y convertirlo a DECIMAL mediante

CAST(<some_value> AS <TARGET_TYPE>)

por ejemplo:

INSERT
     INTO     "TEST_DECIMAL_SEP"
     VALUES (
         NULL,
         CAST('1234567890.12345' AS DECIMAL),
         NULL,
         NULL,
         NULL
);

Ten en cuenta que en este caso  el CAST funcionará si el tipo al cual
deseas convertir es DOUBLE, DECIMAL, NUMERICAL... PERO no INTEGER,
SMALINTEGER etc... porque el valor tiene separador decimal:
'1234567890.12345'. Pero CAST('1234567890' AS INTEGER) *sí* funciona,
por más que el tipo del campo en el cual lo deseas insertar es DECIMAL.
Obviamente, el separador decimal en la cadena de esta función HSQLDB es el *PUNTO*, *no* la COMA. Así que no sales del problema anterior.

Creo que la solución es mantener la configuración regional, y emplear alguna función como la que indiqué arriba para reemplazar la COMA por el PUNTO como separador decimal.

Emplea variables tipo Double, manipula mediante operaciones matemáticas necesarias, y POR ÚLTIMO la conviertes a cadena y reemplazas la como por el punto.

Espero que te sea de ayuda; en cualquier caso, no dudes en consultar y cuenta cómo te ha ido.

Saludos
Ariel

***********************************************************************
NOTA 1:

Si obtienes los datos del control de un formulario, dependerá del tipo de control, y si los obtienes empleando los métodos del control o alguna propiedad del modelo. Para citar sólo dos ejemplos, el "campo formateado" y el "campo numérico":

* UnoControlFormattedField/UnoControlFormattedFieldModel

** UnoControlFormattedField
      XTextComponent::getText()      retorna una cadena
** UnoControlFormattedFieldModel
      UnoControlFormattedFieldModel::EffectiveValue   retorna double
      UnoControlFormattedFieldModel::Text             retorna una cadena


* UnoControlNumericField/UnoControlNumericFieldModel

** UnoControlNumericField
      XTextComponent::getText()               retorna una cadena
      XNumericField::getValue()               retorna double
** UnoControlNumericFieldModel
      UnoControlNumericFieldModel::Value      retorna double








--
Ariel Constenla-Haile
La Plata, Argentina

[EMAIL PROTECTED]
[EMAIL PROTECTED]

http://www.arielconstenlahaile.com.ar/ooo/



"Aus der Kriegsschule des Lebens
                - Was mich nicht umbringt,
        macht mich härter."
                Nietzsche Götzendämmerung, Sprüche und Pfeile, 8.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Responder a