PDA

Ver la Versión Completa : Un método append que funciona en un Grid y falla en un TForm con controles


gorsan
18-03-2014, 23:15:08
Hola de nuevo. Diréis que soy un poco inútil pero me pasa una cosa curiosa que paso a detallaros a continuación:

En un Modulo de datos tengo una IBDataSet y un DataSet apuntando a él.
Sobre un formulario dispongo un Grid enlazado a ese DataSet de modo que el TForm queda encima y el grid debajo y mediante lo siguiente conmuto entre uno y otro:

procedure TWFicha.TBFichaClick(Sender: TObject);
begin
PNEdicion.BringToFront;
GLista.SendToBack;
if TBTabla.Down = True then TBTabla.Down := False;
if TBFicha.Down = False then TBFicha.Down := True;
end;



procedure TWFicha.TBTablaClick(Sender: TObject);
begin
GLista.BringToFront;
PNEdicion.SendToBack;
if TBTabla.Down = False then TBTabla.Down := True;
if TBFicha.Down = True then TBFicha.Down := False;
GLista.SetFocus;
end;


En el formulario dispongo tantos controles DBEdit como campos hay en el grid. Bueno pues la cuestión es que desde el grid el método append funciona perfectamente y añade un nuevo registro sin problemas. Pero si desde el Form dispongo de una botonera para ejecutar el método append y luego el post como sigue:


procedure TWFicha.TBAddClick(Sender: TObject);
begin
TBAdd.Enabled:=False;
TBEditar.Enabled:=False;
TBBorrar.Enabled:=False;
TBGrabar.Enabled:=True;
TBCancelar.Enabled:=True;
TBCargarFoto.Enabled:=False;
TBEliminarFoto.Enabled:=False;
TBCalcular.Enabled:=False;
TBCerrar.Enabled:=False;
TBImprimir.Enabled:=False;
TBSalir.Enabled:=False;
EBuscar.SetFocus;
with DMFicha.IBStoredProc1 do
begin
StoredProcName:='GENERADOR_TRABAJADOR';
Prepare;
ExecProc;
end;
with DMFicha.IBFicha do
try
DisableControls;
Close;
Open;
Append;
finally
EnableControls;
end;

WFicha.DBCONTADOR.Text:=IntToStr(DMFicha.IBStoredProc1.Params[0].Value);
WFicha.DBAlta.Text:=DateToStr(Now);
WFicha.DBBAJA.Text:='';
DMFicha.IBStoredProc1.Close;
DMFicha.IBFicha.Post;
{NuevoRegistro:=True;}
DBPRIMER_APELLIDO.SetFocus;
end;



procedure TWFicha.TBGrabarClick(Sender: TObject);
begin
TBAdd.Enabled:=True;
TBEditar.Enabled:=True;
TBBorrar.Enabled:=True;
TBGrabar.Enabled:=False;
TBCancelar.Enabled:=False;
TBCargarFoto.Enabled:=True;
TBEliminarFoto.Enabled:=True;
TBCalcular.Enabled:=True;
TBCerrar.Enabled:=True;
TBImprimir.Enabled:=True;
TBSalir.Enabled:=True;
DMFicha.IBFicha.Edit;
DMFicha.IBFicha.Post;
end;


Otra cosa curiosa es que sobre los controles del Form puedo editar los datos y guarda los cambios directamente sin el post pero no permite el método append lanzando la siguiente excepción:
"cannot focus a disabled or invisible window"
Alguna idea. Seguro que es la tontería mas grande del mundo pero no lo veo.

ecfisa
19-03-2014, 02:39:12
Hola gorsan.

La verdad me cuesta entender la situación, por ejemplo:
Sobre un formulario dispongo un Grid enlazado a ese DataSet de modo que el TForm queda encima y el grid debajo
¿ Como logras eso ?

Además hay controles como GLista, PNEdicion, WFicha que no imagino la clase y no me queda en claro cuál es su función


Otra cosa curiosa es que sobre los controles del Form puedo editar los datos y guarda los cambios directamente sin el post pero no permite el método append lanzando la siguiente excepción:
"cannot focus a disabled or invisible window"
Ese error es provocado por darle el foco (SetFocus) a un control que en ese momento, tiene su propiedad Visible o Enabled en False.
Hay tres puntos donde llamas al método SetFocus:

procedure TWFicha.TBTablaClick(Sender: TObject);
begin
...
GLista.SetFocus; // (1)
end;

procedure TWFicha.TBAddClick(Sender: TObject);
begin
...
EBuscar.SetFocus; // (2)
...
DBPRIMER_APELLIDO.SetFocus; // (3)
end;

Con seguridad la provoca una (o mas) de ellas.

Saludos :)

gorsan
19-03-2014, 08:29:48
Buenos días.
Muchas gracias por responder. Se agradece.
No. No parece ser ese el caso ya que he deshabilitado las tres sentencias que señalas y el errror sigue produciendose.
Intentaré explicar un poco el concepto del programa.

Lo del Grid y el Form: es solo una forma alternativa de presentar al usuario, segun su iniciativa, los datos de una tabla, ya que ambos estan conectados al mismo DataSource que enlaza con la tabla. Si pulsa el boton "ficha" aparece lo que llamo la ficha que no es mas que un panel, PNEdition, con los controles DBEdit conectados a los distintos campos de la tabla. Si pulsa el boton "tabla" se presenta el grid que está debajo y que apunta a los mismos datos mediante el metodo GLista.BringToFront; y el panel PNEdicion con los controles DBEdit pasan a un segundo plano mediante el metodo PNEdition.SendToBack;
Sinceramente, no creo que el problema esté aquí. De hecho, he eliminado las 3 referencias al foco y la excepcion sigue produciendose.

Mi idea primera era que solo se puedieran añadir registros a la tabla a traves de la "ficha" mediante un boton (TBAdd: TToolButton) y con el codigo que expongo en mi anterior post, ya que cada nuevo registro lleva un número unico que se produce con un generador que manejo desde la BD (campo contador). Por tanto que desde el grid no se permitiera el metodo append, solo la edicion de los datos de los campos. Para ello disponía:

procedure TDMFicha.IBFichaBeforeInsert(DataSet: TDataSet);
begin
if WFicha.GLista.Focused then abort;
if WNomina.GListaN.Focused then abort;
end;

Digo disponia porque este codigo fue lo primero que descarté al comenzar a darse el error. Una vez descartado compruebo con asombro como desde el Grid sí que puedo añadir un registro y no solo editar los anteriores.
Por tanto y concluyendo, desde los dbedit que estan sobre el PNEdicion se editan los datos que ya estan en la tabla pero cuando pretendo añadir un nuevo registro, sobre estos mismos controles, e introduzco los nuevos datos de este, falla al hacer el metodo post dando la excepcion que comento.
No se si he aclarado el "pastel" que tengo liado pero lo de bringtofront y sendtoback no creo sea el problema y lo del setfocus tampoco.
Muchas gracias por vuestro esfuerzo.

Neftali [Germán.Estévez]
19-03-2014, 12:34:55
Estoy bastante de acuerdo con ecfisa. Ese error normalmente está provocado por el SetFocus o similares, cuando un control se encuentra no visible o no accesible. Por ejemplo, cuando está en un TabSheet que no es activo.
Piensa que a veces el SetFocus se puede llamar de forma indirecta, cuando activas ventanas, cuando se ejecuta SetActiveControl,...

gorsan
19-03-2014, 16:06:18
Gracias Neftalí.
No entiendo nada. He inhabilitado las sentencias que dice ecfisa pero sigue produciéndose la excepción. Si estoy escribiendo sobre controles DBEdit entiendo que el foco del teclado lo tiene el contenedor del componente DBEdit, pero la excepción salta cuando hago un método post contra el DataSet que está admitiendo las actualizaciones de los datos. Entiendo que lo que falla, y no se porque, es el método append del TIBDataSet que soporta los datos. El tinglao tiene que estar por otro sitio ...

ecfisa
19-03-2014, 18:48:58
Hola gorsan.

Ya con los datos que me faltaban en mano, una tabla de prueba y dejando de lado las llamadas al TIBStoredProc, pude reproducir tu caso sin obtener ningún error.

Este es el código de la prueba:

...
procedure TWFicha.btnFichaClick(Sender: TObject);
begin
PNEdicion.BringToFront;
GLista.SendToBack;
if TBTabla.Down = True then TBTabla.Down := False;
if TBFicha.Down = False then TBFicha.Down := True;
end;

procedure TWFicha.btnTablaClick(Sender: TObject);
begin
GLista.BringToFront;
PNEdicion.SendToBack;
if TBTabla.Down = False then TBTabla.Down := True;
if TBFicha.Down = True then TBFicha.Down := False;
GLista.SetFocus;
end;


procedure TWFicha.TBAddClick(Sender: TObject);
begin
TBAdd.Enabled:=False;
TBEditar.Enabled:=False;
TBBorrar.Enabled:=False;
TBGrabar.Enabled:=True;
TBCancelar.Enabled:=True;
TBCargarFoto.Enabled:=False;
TBEliminarFoto.Enabled:=False;
TBCalcular.Enabled:=False;
TBCerrar.Enabled:=False;
TBImprimir.Enabled:=False;
TBSalir.Enabled:=False;
EBuscar.SetFocus;
{
with DMFicha.IBStoredProc1 do
begin
StoredProcName:='GENERADOR_TRABAJADOR';
Prepare;
ExecProc;
end;
}

with DMFicha.IBFicha do
try
DisableControls;
{ ???????
Close;
Open;
}
Append;
finally
EnableControls;
end;

WFicha.DBCONTADOR.Text:= '123';//IntToStr(DMFicha.IBStoredProc1.Params[0].Value);
WFicha.DBAlta.Text:=DateToStr(Now);
WFicha.DBBAJA.Text:='';
// DMFicha.IBStoredProc1.Close;
DMFicha.IBFicha.Post;
DBPRIMER_APELLIDO.SetFocus;
end;

procedure TWFicha.TBGrabarClick(Sender: TObject);
begin
TBAdd.Enabled:=True;
TBEditar.Enabled:=True;
TBBorrar.Enabled:=True;
TBGrabar.Enabled:=False;
TBCancelar.Enabled:=False;
TBCargarFoto.Enabled:=True;
TBEliminarFoto.Enabled:=True;
TBCalcular.Enabled:=True;
TBCerrar.Enabled:=True;
TBImprimir.Enabled:=True;
TBSalir.Enabled:=True;
DMFicha.IBFicha.Edit;
DMFicha.IBFicha.Post;
end;
...


¿ Seguro que no hay mas código involucrado ? ¿ Algo en algún evento ?

Saludos :)

gorsan
19-03-2014, 23:07:51
Hola ecfisa. Muchas gracias por tu ayuda y por "pegarte" con mi farragoso código. Ahí va más porque sí, hay más código implicado.
Si tienes paciencia échale un vistazo a ver si ves algo que te llame la atención en el sentido que nos ocupa. Se trata del módulo de datos donde están alojados los componentes que manejan los datos. Si, ya se, es un pantano. Pero yo no veo aquí tampoco el núcleo del error que nos ocupa. En tres veces por los problemas de numero máximo de caracteres admitidos:


unit Mod_Dat2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ComCtrls, StdCtrls, Mask, DBCtrls, ExtCtrls, ToolWin,
ExtDlgs, jpeg, DB, Buttons, IBCustomDataSet, IBSQL, IBDatabase,
IBStoredProc, RpDefine, RpCon, RpConDS, RpRave, RpBase, RpSystem, IBQuery,
RpConBDE;

type
TDMFicha = class(TDataModule)
IBFicha: TIBDataSet;
DSFicha: TDataSource;
IBTLocal_Ficha: TIBTransaction;
IBStoredProc1: TIBStoredProc;
IBFichaCONTADOR: TIntegerField;
IBFichaPRIMER_APELLIDO: TIBStringField;
IBFichaSEGUNDO_APELLIDO: TIBStringField;
IBFichaNOMBRE: TIBStringField;
IBFichaMODULO: TIntegerField;
IBFichaTALLER: TIBStringField;
IBFichaTURNO: TIBStringField;
IBFichaALTA: TDateField;
IBFichaBAJA: TDateField;
IBFichaFOTO: TBlobField;
IBFichaOBSERVACIONES: TMemoField;
IBFichaFORMATO: TIBStringField;
IBFichaDIA_1: TIBStringField;
IBFichaDIA_2: TIBStringField;
IBFichaDIA_3: TIBStringField;
IBFichaDIA_4: TIBStringField;
IBFichaDIA_5: TIBStringField;
IBFichaDIA_6: TIBStringField;
IBFichaDIA_7: TIBStringField;
IBFichaDIA_8: TIBStringField;
IBFichaDIA_9: TIBStringField;
IBFichaDIA_10: TIBStringField;
IBFichaDIA_11: TIBStringField;
IBFichaDIA_12: TIBStringField;
IBFichaDIA_13: TIBStringField;
IBFichaDIA_14: TIBStringField;
IBFichaDIA_15: TIBStringField;
IBFichaDIA_16: TIBStringField;
IBFichaDIA_17: TIBStringField;
IBFichaDIA_18: TIBStringField;
IBFichaDIA_19: TIBStringField;
IBFichaDIA_20: TIBStringField;
IBFichaDIA_21: TIBStringField;
IBFichaDIA_22: TIBStringField;
IBFichaDIA_23: TIBStringField;
IBFichaDIA_24: TIBStringField;
IBFichaDIA_25: TIBStringField;
IBFichaDIA_26: TIBStringField;
IBFichaDIA_27: TIBStringField;
IBFichaDIA_28: TIBStringField;
IBFichaDIA_29: TIBStringField;
IBFichaDIA_30: TIBStringField;
IBFichaDIA_31: TIBStringField;
IBFichaHORAS_REALES: TIntegerField;
IBFichaHORAS_CALCULADAS: TIntegerField;
IBFichaSALARIO: TFloatField;
IBFichaANO: TSmallintField;
IBFichaMES: TIBStringField;
RvDataSetConnection1: TRvDataSetConnection;
RvProject1: TRvProject;
IBQGeneral_Taller_Turno: TIBQuery;
IBQNomina_Taller_Turno: TIBQuery;
RvDataSetConnection2: TRvDataSetConnection;
RvProject2: TRvProject;
IBQuery1: TIBQuery;
IBQuery2: TIBQuery;
IBQuery3: TIBQuery;
IBQuery4: TIBQuery;
procedure IBFichaAfterDelete(DataSet: TDataSet);
procedure IBFichaAfterPost(DataSet: TDataSet);
procedure DSFichaDataChange(Sender: TObject; Field: TField);
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
procedure Buscar(Campo, Texto : string);
procedure Ordena(Campo, Orientacion: String);
procedure Calcular_HorasTrabajadas;
procedure IBFichaBeforeInsert(DataSet: TDataSet);
procedure Calculo_Horas_Minoradas;
function ReduccionHoras(HR: integer; FC: double; PH: double):double;
function CalculoSalario(HC: double; PH: double):double;
procedure CreateTable(const TableName1: string);
procedure CreateTableParametros(const TableName2: string);
procedure CreateTableTotales(const TableName3: string);
private
{ Private declarations }
FOriginalSQL : string;
public
{ Public declarations }
end;

var
DMFicha: TDMFicha;

implementation

uses Man_Ficha, Man_Nomina, Mod_Dat5, Mod_Dat1, Apertura, Apertura2;

{$R *.dfm}

procedure TDMFicha.IBFichaAfterDelete(DataSet: TDataSet);
begin
IBFicha.Transaction.CommitRetaining;
IBFicha.Refresh;
end;

procedure TDMFicha.IBFichaAfterPost(DataSet: TDataSet);
begin
IBFicha.Transaction.CommitRetaining;
IBFicha.Refresh;
end;

procedure TDMFicha.DSFichaDataChange(Sender: TObject; Field: TField);
var
m: TStream;
begin
if IBFichaFOTO.IsNull then
//para registros sin imagen poner imagen vacia.
WFicha.Image2.Picture:=nil
else
begin
if IBFichaFORMATO.AsString='BMP' then
//si es formato BMP
WFicha.Image2.Picture.Graphic:=TBitmap.Create
else if IBFichaFORMATO.AsString='JPG' then
//si es formato JPG
WFicha.Image2.Picture.Graphic:=TJpegImage.Create
else
Exit;
//copiar los datos desde la tabla con un stream
m:=IBFicha.CreateBlobStream(IBFichaFOTO, bmRead);
WFicha.Image2.Picture.Graphic.LoadFromStream(m);
m.Free;
end;
With WFicha.StatusBar1 do
begin
Panels[0].Text:=' Registros -> '+IntToStr(DMFicha.IBFicha.RecordCount);
Panels[1].Text:=' '+DMFicha.IBFicha.FieldByName('PRIMER_APELLIDO').asString;
Panels[2].Text:=' '+DMFicha.IBFicha.FieldByName('SEGUNDO_APELLIDO').asString;
Panels[3].Text:=' '+DMFicha.IBFicha.FieldByName('NOMBRE').asString;
Panels[4].Text:=' '+DMFicha.IBFicha.FieldByName('MODULO').asString;
Panels[5].Text:=' '+DMFicha.IBFicha.FieldByName('TALLER').asString;
Panels[6].Text:=' '+DMFicha.IBFicha.FieldByName('TURNO').asString;
end;
end;

procedure TDMFicha.DataModuleCreate(Sender: TObject);
begin
IBTLocal_Ficha.StartTransaction;
FOriginalSQL := IBFicha.SelectSQL.Text;
end;

procedure TDMFicha.DataModuleDestroy(Sender: TObject);
begin
IBTLocal_Ficha.Commit;
end;

procedure TDMFicha.Buscar(Campo, Texto : string);
begin
if (TallerFicha<>'') and (TallerNomina='') then FOriginalSQL:='SELECT * FROM '+TallerFicha;
if (TallerFicha='') and (TallerNomina<>'') then FOriginalSQL:='SELECT * FROM '+TallerNomina;
if (TallerFicha<>'') and (TallerNomina<>'') then FOriginalSQL:='SELECT * FROM '+TallerFicha;
With IBFicha do
try
// Desconectamos los controles
DisableControls;
// Cerramos
Close ;
// Restablecemos la sentencia original
SelectSQL.Clear;
SelectSQL.Add(FOriginalSQL);
// Si no se ha de buscar nada, se abre la tabla y se sale
if Texto = '' then
begin
Open;
Last;
First;
Exit;
end;
SelectSQL.Add('WHERE '+Campo+' LIKE '+QuotedStr(Texto+ '%'));
// Ordenamos por el campo que se hace la busqueda
SelectSQL.Add('ORDER BY '+Campo);
Open ;
finally
// Conectamos los controles
EnableControls;
end;
end;

procedure TDMFicha.Ordena(Campo, Orientacion: String);
var
I: integer;
begin
with IBFicha do
try
DisableControls;
Close;
for I:=SelectSQL.Count - 1 downto 0 do
if pos('ORDER BY', uppercase(SelectSQL[I])) <> 0 then SelectSQL.Delete(I);
SelectSQL.Add('ORDER BY '+Campo+Orientacion);
Open;
Last;
First;
finally
EnableControls;
end;
end;

procedure TDMFicha.Calcular_HorasTrabajadas;
var
Numero_Jornadas: integer;
begin
{CÁLCULO DE LAS HORAS REALES}
{Se cuentan las X y se multiplica por 4 horas si el turno es M o T; o por 8 si es M-T}
Numero_Jornadas:=0;
if DMFicha.IBFichaDIA_1.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_2.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_3.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_4.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_5.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_6.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_7.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_8.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_9.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_10.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_11.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_12.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_13.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_14.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_15.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_16.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_17.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_18.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_19.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_20.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_21.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_22.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_23.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_24.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_25.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_26.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_27.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_28.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_29.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_30.AsString ='X' then Inc(Numero_Jornadas);
if DMFicha.IBFichaDIA_31.AsString ='X' then Inc(Numero_Jornadas);
DMFicha.IBFicha.Edit;
if DMFicha.IBFichaTURNO.AsString ='M' then DMFicha.IBFichaHORAS_REALES.AsInteger:= (Numero_Jornadas*4);
if DMFicha.IBFichaTURNO.AsString ='T' then DMFicha.IBFichaHORAS_REALES.AsInteger:= (Numero_Jornadas*4);
if DMFicha.IBFichaTURNO.AsString ='M-T' then DMFicha.IBFichaHORAS_REALES.AsInteger:= (Numero_Jornadas*8);
DMFicha.IBFicha.Post;
end;

procedure TDMFicha.IBFichaBeforeInsert(DataSet: TDataSet);
begin
{Para impedir que desde el WFicha.DbGrid cuando estas con los cursores y llegas
al ultimo te añada un registro en blanco.
{if WFicha.GLista.Focused then abort;
if WNomina.GListaN.Focused then abort;}
end;

gorsan
19-03-2014, 23:20:54
No me se me permite por razones de cupo o algo así, enviar el resto de la unit que contiene el módulo de datos.
¿Existe la posibilidad de hacerlo en un *.txt?

ecfisa
20-03-2014, 00:24:51
Hola gorsan.
N
¿Existe la posibilidad de hacerlo en un *.txt?
Si por supuesto. Guarda el código en un archivo .txt, comprimilo y adjuntalo al mensaje, mediante el ícono clip:

http://sia1.subirimagenes.net/img/2014/03/20/140320122046452919.jpg

Saludos.:)

Casimiro Notevi
20-03-2014, 01:06:23
y adjuntalo al mensaje, mediante el ícono clip:
Nunca me había fijado en ese icono :eek:, siempre lo he hecho desde el botón "Gestionar Archivos Adjuntos" que está un poco más abajo..

gorsan
20-03-2014, 07:26:46
Siento discrepar pero a mi no me sale el icono que muestras, en su lugar, es decir, inmediatamente a la izquierda de los iconos deshacer y rehacer, tengo una especie de combo que pone archivos adjuntos y el desplegable de persiana no hace nada. No se como subir un fichero salvo por e-mail.
Gracias por vuestras respuestas.

ecfisa
20-03-2014, 08:35:21
Hola gorsan.

Debes tener algún problema con el navegador o su configuración, acabo de crear un usuario con 0 mensajes para descartar cualquier restricción por el número de mensajes.
Y tanto con Mozilla Firefox como con Internet Explorer visualizo y puedo acceder por el ícono que te mencioné y también por el que indicó Casimiro.

Saludos :)

gorsan
20-03-2014, 09:04:48
Una vez resuelto el problema adjunto el fichero con el codigo.

gorsan
21-03-2014, 08:54:32
Hola. Buenos dias.
Ya he dado con el problema. Me ha traido de cabeza porque el mensaje "cannot focus a disabled or invisible window" no me daba las pistas adecuadas, mas bien al contrario.
Las prisas no son buenas y yo tenía que entregar la aplicación cuanto antes. Debido a un cambio de ultima hora del cliente (el comprador del programa) tuve que rehacer el planteamiento de la base de datos desde inicio con un montón de código ya hecho. Entonces me sobraba un campo. Ese campo estaba con su control data-aware sobre el formulario ficha. Pues nada lo eliminé sin darme cuenta de que estaba declarado como not null. Error imperdonable. Desde el formulario saltaba el error al invocar el metodo append y dejar ese campo en blanco. Desde el grid no saltaba el error porque como lo metia a mano pues no daba el error. Pero no me digais que el tenor literal del error no da ninguna pista acerca de esto. Deberia haber sido la base de datos la que se quejara de alguna manera ¿no?
En todo caso, muchas gracias a ecfisa por su tiempo y a todos los demas que os habeis interesado.
Doy por concluido este hilo. Un saludo para todos y salud.

ecfisa
21-03-2014, 19:16:03
Hola gorsan.
Pero no me digais que el tenor literal del error no da ninguna pista acerca de esto. Deberia haber sido la base de datos la que se quejara de alguna manera ¿no?

Si, realmente no es orientativo en este caso... Me alegra que lo encontraras ^\||/

Saludos :)