Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   No hay calculos al insertar en la tabla (https://www.clubdelphi.com/foros/showthread.php?t=91526)

aguml 25-02-2017 14:22:01

No hay calculos al insertar en la tabla
 
Sigo liado con esto y ahora he colocado un TEdit el cual me devuelve el total a pagar por el cliente. Si abro una tabla de un cliente me sale el total, si inserto una linea tambien, si elimino una linea tambien.
El problema lo tengo cuando no existia la tabla y la crea, ahi si inserto o elimino algun producto al DBGrid no surte efecto y el total siempre es 0. Si cambio de cliente y vuelvo a abrir el que he creado ya si funciona bien.
Este es el codigo que tengo ahora mismo:
Unit1.cpp:
Código PHP:

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
#include "Unit3.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "ZAbstractDataset"
#pragma link "ZAbstractRODataset"
#pragma link "ZAbstractTable"
#pragma link "ZConnection"
#pragma link "ZDataset"
#pragma resource "*.dfm"
TFormMain *FormMain;
bool bloqueado,abierta;
//---------------------------------------------------------------------------
__fastcall TFormMain::TFormMain(TComponentOwner)
    : 
TForm(Owner)
{
    
bloqueado=true;
    
abierta=false;
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::ButtonAddConsumisionClick(TObject *Sender)
{
    
FormProductos->ShowModal();
    
FormProductos->EditBusqueda->Text "";
    
EditTotal->Text=GetTotal(ZQueryClientes,DataSourceClientes,"Precio");
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::ButtonSelectClienteClick(TObject *Sender)
{
    if(
ComboBox1->Text == ""){
        
Application->MessageBoxA("Debe introducir un nombre de cliente válido.","Atención",MB_OK MB_ICONINFORMATION);
        return;
    }

    
int retval;

    
ZQueryClientes->Connection ZConnection;
    
ZTableClientes->Connection ZConnection;
    
ZTableClientes->TableName ComboBox1->Text;
    
DataSourceClientes->DataSet ZTableClientes;
    
DBGridClientes->DataSource DataSourceClientes;

    
AnsiString Cadena_SQL//Cadena del comando SQL a ejecutar
    
if(!ZConnection->Connected)
        
ZConnection->Connect(); //me conecto a la BD

    
Cadena_SQL "SELECT * FROM " ComboBox1->Text;
    
ZQueryClientes->SQL->Clear(); //se limpia la cadena SQL existente
    
ZQueryClientes->SQL->Text=Cadena_SQL//cargo el comando SQL a ejecutar
    
try{
        
ZQueryClientes->ExecSQL(); //Ejecuto el comando
    
}catch(...){
        
retval Application->MessageBoxA("El cliente no existe. ¿Desea crearlo?","Atención",MB_YESNO MB_ICONINFORMATION);
        if(
retval == IDYES){
            
Cadena_SQL="CREATE TABLE IF NOT EXISTS \"main\".\"" ComboBox1->Text "\" (\"Nombre\" VARCHAR(50),\"Unidades\" REAL,\"Precio\" REAL,\"Total\" REAL)";
            
ZQueryClientes->SQL->Clear(); //se limpia la cadena SQL existente
            
ZQueryClientes->SQL->Text=Cadena_SQL//cargo el comando SQL a ejecutar
            
ZQueryClientes->ExecSQL(); //Ejecuto el comando
            
ComboBox1->Items->Add(ComboBox1->Text);
        }else{
            return;
        }
    }
    
//En este punto la tabla ya esta creada por lo tanto ya se puede abrir
    //el componente de TABLA
    
ZTableClientes->Open();
    
//Ajustamos el ancho de las columnas para que se vean mejor
    
DBGridClientes->Columns->operator [](0)->Width=250;
    
DBGridClientes->Columns->operator [](1)->Width=65;
    
DBGridClientes->Columns->operator [](2)->Width=65;
    
DBGridClientes->Columns->operator [](3)->Width=65;

    
ButtonAddConsumision->Enabled true;
    if(!
bloqueado){
        
ButtonDelLine->Enabled true;
        
ButtonEliminarCli->Enabled true;
    }
    
abierta=true;
}
//---------------------------------------------------------------------------
double __fastcall TFormMain::GetTotal(TZQuery *ZQueryTDataSource *DataSourcechar *nombreCol)
{
    
double Total=0;
    
ZQuery->DataSource DataSource;
    
ZQuery->Open();
    
ZQuery->First();
    while(!
ZQuery->Eof){
        
Total+=ZQuery->FieldByName(nombreCol)->Text.ToDouble();
        
ZQuery->Next();
    }
    
ZQuery->Close();
    return 
Total;
}
//---------------------------------------------------------------------------

void __fastcall TFormMain::ButtonEliminarCliClick(TObject *Sender)
{
    
AnsiString Cadena_SQL//Cadena del comando SQL a ejecutar
    
if(!ZConnection->Connected)
        
ZConnection->Connect();

    
Cadena_SQL "DROP TABLE IF EXISTS \"main\".\"" ComboBox1->Text "\"";
    
ZQueryClientes->SQL->Clear(); //se limpia la cadena SQL existente
    
ZQueryClientes->SQL->Text=Cadena_SQL//cargo el comando SQL a ejecutar
    
ZTableClientes->Close();
    
ZQueryClientes->ExecSQL(); //Ejecuto el comando
    
DBGridClientes->DataSource NULL;

    for(
int i=0;i<ComboBox1->Items->Count;i++)
    {
        if(
ComboBox1->Items->operator [](i)==ComboBox1->Text)
        {
            
ComboBox1->Items->Delete(i);
            break;
        }
    }
    
ButtonAddConsumision->Enabled false;
    
ButtonDelLine->Enabled false;
    
ButtonEliminarCli->Enabled false;
    
abierta=false;
    
EditTotal->Text="";
}
//---------------------------------------------------------------------------

void __fastcall TFormMain::ButtonDelLineClick(TObject *Sender)
{
    if(!
ZTableClientes->IsEmpty()){
        
ZTableClientes->Delete();
    }
}
//---------------------------------------------------------------------------

void __fastcall TFormMain::ButtonAdminClick(TObject *Sender)
{
    
AnsiString cadena;
    
int result;
    
    if(
ButtonAdmin->Caption == "Ir al modo Administrador"){
        
FormLogin->MaskEdit1->Text="";
        
result=FormLogin->ShowModal();
        if(
result==mrOk){
            
bloqueado=false;
            
ButtonAdmin->Caption "Ir al modo Usuario";
            if(
abierta==true){
                
ButtonDelLine->Enabled true;
                
ButtonEliminarCli->Enabled true;
            }
        }else if(
result==mrNo){
            
Application->MessageBoxA("Ha introducido una contraseña incorrecta. No se ha desbloqueado la lista.","Contraseña incorrecta",MB_OK MB_ICONERROR);
        }
    }else{
        
bloqueado=true;
        
ButtonAdmin->Caption "Ir al modo Administrador";
        
ButtonDelLine->Enabled false;
        
ButtonEliminarCli->Enabled false;
    }
}
//---------------------------------------------------------------------------

void __fastcall TFormMain::FormClose(TObject *SenderTCloseAction &Action)
{
    if(
FormProductos->ZQueryProductos->Active)
        
FormProductos->ZQueryProductos->Close();
    if(
FormProductos->ZTableProductos->Active)
        
FormProductos->ZTableProductos->Close();
    if(
ZQueryClientes->Active)
        
ZQueryClientes->Close();
    if(
ZTableClientes->Active)
        
ZTableClientes->Close();
    if(
ZConnection->Connected)
        
ZConnection->Disconnect();
}
//---------------------------------------------------------------------------

void __fastcall TFormMain::DataSourceClientesDataChange(TObject *Sender,
      
TField *Field)
{
    
EditTotal->Text=GetTotal(ZQueryClientes,DataSourceClientes,"Precio");
}
//--------------------------------------------------------------------------- 

Unit2.cpp:
Código PHP:

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
#include "Unit3.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "ZAbstractDataset"
#pragma link "ZAbstractRODataset"
#pragma link "ZAbstractTable"
#pragma link "ZDataset"
#pragma link "ZConnection"
#pragma resource "*.dfm"
TFormProductos *FormProductos;
//---------------------------------------------------------------------------
__fastcall TFormProductos::TFormProductos(TComponentOwner)
    : 
TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TFormProductos::FormCreate(TObject *Sender)
{
    if(!
FormMain->ZConnection->Connected)
    {
        
FormMain->ZConnection->Protocol "sqlite-3";
        
FormMain->ZConnection->Database "clientesDB.sqlite";
        
ZQueryProductos->Connection FormMain->ZConnection;
        
ZTableProductos->Connection FormMain->ZConnection;
        
ZTableProductos->TableName "Articulos";
        
DataSourceProductos->DataSet ZTableProductos;
        
DBNavigatorProductos->DataSource DataSourceProductos;
        
DBGridProductos->DataSource DataSourceProductos;

        
AnsiString Cadena_SQL//Cadena del comando SQL a ejecutar
        
FormMain->ZConnection->Connect(); //me conecto a la BD
        
Cadena_SQL="CREATE TABLE IF NOT EXISTS \"main\".\"Articulos\" (\"Nombre\" VARCHAR(50),\"Precio\" REAL)";
        
ZQueryProductos->SQL->Clear(); //se limpia la cadena SQL existente
        
ZQueryProductos->SQL->Text=Cadena_SQL//cargo el comando SQL a ejecutar
        
ZQueryProductos->ExecSQL(); //Ejecuto el comando
        //En este punto la tabla ya esta creada por lo tanto ya se puede abrir
        //el componente de TABLA
        
ZTableProductos->Open();
        
//Ajustamos el ancho de las columnas para que se vean mejor
        
DBGridProductos->Columns->operator [](0)->Width=250;
        
DBGridProductos->Columns->operator [](1)->Width=60;
    }
    
FormMain->ComboBox1->Items->Clear();

    
FormMain->ZConnection->GetTableNames("",FormMain->ComboBox1->Items);
    for(
int i=0;i<FormMain->ComboBox1->Items->Count;i++)
    {
        if(
FormMain->ComboBox1->Items->operator [](i)=="Articulos")
        {
            
FormMain->ComboBox1->Items->Delete(i);
            
i--;
        }
    }
}
//---------------------------------------------------------------------------
void __fastcall TFormProductos::DBGridProductosCellClick(TColumn *Column)
{
    
TDataSet *DS static_cast<TDataSet*>( DBGridProductos->DataSource->DataSet );

    
EditNombre->Text DS->FieldByName("Nombre")->AsString;
    
EditPrecio->Text DS->FieldByName("Precio")->AsString;

    if ( 
EditUnidades->Text != "" && EditPrecio->Text != "" )
        
EditTotal->Text EditUnidades->Text.ToDouble() * EditPrecio->Text.ToDouble();
}
//---------------------------------------------------------------------------
void __fastcall TFormProductos::EditUnidadesExit(TObject *Sender)
{
    if(
EditUnidades->Text != "" && EditPrecio->Text != "")
        
EditTotal->Text EditUnidades->Text.ToDouble() * EditPrecio->Text.ToDouble();
}
//---------------------------------------------------------------------------
void __fastcall TFormProductos::ButtonDesbloquearClick(TObject *Sender)
{
    
AnsiString cadena;
    
int result;
    if(
ButtonDesbloquear->Caption == "Editar lista")
    {
        
FormLogin->MaskEdit1->Text="";
        
result=FormLogin->ShowModal();
        if(
result==mrOk){
            
DBGridProductos->ReadOnly false;
            
DBGridProductos->Options  TDBGridOptions(DBGridProductos->Options) >> dgRowSelect << dgEditing;
            
DBNavigatorProductos->Enabled true;
            
ButtonDesbloquear->Caption "Proteger lista";
        }else if(
result==mrNo){
            
ShowMessage("Contraseña incorrecta. No se ha desbloqueado la lista.");
        }
    }else{
        
DBGridProductos->ReadOnly true;
        
DBGridProductos->Options  TDBGridOptions(DBGridProductos->Options) << dgRowSelect >> dgEditing;
        
DBNavigatorProductos->Enabled false;
        
ButtonDesbloquear->Caption "Editar lista";
    }
}
//---------------------------------------------------------------------------

void __fastcall TFormProductos::ButtonAddConsumisionClick(TObject *Sender)
{
    if(
EditNombre->Text !="" && EditPrecio->Text !="" && EditUnidades->Text !="" && EditPrecio->Text !="" && EditUnidades->Text !="")
    {
        
FormMain->ZTableClientes->Insert();
        
FormMain->ZTableClientes->FieldByName("Nombre")->Text EditNombre->Text//se carga el valor de la edad
        
FormMain->ZTableClientes->FieldByName("Unidades")->Text EditUnidades->Text.ToDouble();
        
FormMain->ZTableClientes->FieldByName("Precio")->Text EditPrecio->Text.ToDouble();
        
FormMain->ZTableClientes->FieldByName("Total")->Text EditTotal->Text.ToDouble();
        
FormMain->ZTableClientes->Post();  //se ejecuta la inserccion
    
}
}
//---------------------------------------------------------------------------

void __fastcall TFormProductos::EditBusquedaChange(TObject *Sender)
{
    
ZTableProductos->Filter "Nombre LIKE '*" EditBusqueda->Text "*'";
    
ZTableProductos->FilterOptions TFilterOptions(ZQueryProductos->FilterOptions) << foCaseInsensitive;
    
ZTableProductos->Filtered=(EditBusqueda->Text != "");
}
//--------------------------------------------------------------------------- 


Casimiro Notevi 25-02-2017 15:27:02

No enteindo cómo trabajas, creando tablas en tiempo de ejecución :confused:

aguml 25-02-2017 15:47:23

La idea es que si creo un nuevo cliente ese cliente es una tabla y como no existe tengo que crearla para guardar en ella sus consumisiones.

Casimiro Notevi 25-02-2017 16:04:37

Cita:

Empezado por aguml (Mensaje 513708)
La idea es que si creo un nuevo cliente ese cliente es una tabla y como no existe tengo que crearla para guardar en ella sus consumisiones.

¿Tienes una tabla por cliente? :eek:

aguml 25-02-2017 17:14:49

¿cómo lo harías tu? La única manera que se me ocurre seria una tabla para todos y tener un campo para controlar con filtrados que mostrar y así a la hora de mostrar el listado de clientes seria más complejo ya que tendría que ir comprobando al crear un cliente que este ya no exista mientras que como lo hago so lo necesito leer los nombres de las tablas. Además si son muchos clientes la tabla podría ser enorme y hacer filtrados con tablas enormes creo que es bastante más ineficiente que tener una tabla por cliente y además así queda más ordenado ya que quitando la tabla artículos el resto son clientes.

Casimiro Notevi 25-02-2017 19:09:12

Por supuesto, una tabla de clientes, para todos los clientes, es tan fácil como tener un campo codigo.
Código SQL [-]
create table tbClientes (
  id integer not null,
  nombre varchar(128),
  telefono varchar(16) default '',
  etc...
);

Luego el filtro es facilísimo:
Código SQL [-]
select * from tbClientes where id= CodigoDelCliente

aguml 25-02-2017 21:42:32

¿Y que beneficio tiene hacerlo así VS crear una tabla por cliente?

Caminante 25-02-2017 22:19:41

Hola

La verdad creo que es preferible tener una tabla con muchos clientes que tener muchas tablas de clientes. El primer beneficio que se me viene a la mente es lo mas comun si necesito un listado ordenado de clientes.

Código SQL [-]
Select Nombre, Apellidos, etc... from Clientes where .... etc   order by Nombre

Como harias eso con varias tablas???

Bueno solo es mi punto de vista

Saludos

aguml 26-02-2017 00:29:44

¿Y como harías para mostrar sólo la columna de nombres de los clientes teniendo en cuenta que sólo debe mostrar 1 vez cada nombre? Lo digo porque esta tabla contendría consumiciones de clientes y un cliente podría tener varias consumiciones por lo que si haces:
Código PHP:

Select Nombre from Clientes order by Nombre 

Yo en mi código meto todos los nombres de las tablas en un combobox y luego simplemente elimino el ítem donde está el nombre Artículos y lo hago con tres líneas de código ¿cómo harías eso con una sola tabla? Supongo que tendrías que ir leyendo el Nombre de cada fila y si no está ya en el combobox añadirlo a este pero eso implica moverse y leer toda la tabla y con tablas grandes no se que tan eficiente seria con respecto a lo que hago yo.

aguml 26-02-2017 00:57:21

Después de buscar información creo que cualquiera de estas dos líneas me devolvería un listado de los nombres sin repetir pero mi inglés es muy malo y no se si hace realmente lo que necesito:
Código SQL [-]
SELECT Nombre, COUNT(*) c FROM Articulos GROUP BY Nombre HAVING c > 1
o:
Código SQL [-]
SELECT DISTINCT Nombre FROM Articulos
¿alguien me puede explicar que hace cada una de esas líneas y si están correctas para lo que quiero hacer?

Casimiro Notevi 26-02-2017 01:14:48

Imagina un bar donde para atender un cliente necesitan a un camarero, cuando llega otro cliente ¿contratan a otro camarero?, ¿si hay 100 clientes, contratan a 100 camareros?
Pues eso es lo que estás haciendo tú creando una tabla distinta para cada cliente.

Imagina que tienes un millón de clientes, ¿tendrías un millón de tablas? ¿cómo buscas los clientes de una ciudad, o de cierta edad, o que consuman cierto artículo, etc.?
Las consumisiones tienen que ir en otra tabla. La relación es simple:
Tabla clientes: id, nombre, edad, etc.
Tabla articulos: id, codigo, nombre, etc.
Tabla consumisiones, id, fecha, numero, idcliente, idarticulo, cantidad, precio, etc.

Aparte de eso, necesitas leer un estupendo libro, la cara oculta de delphi 4 o la cara oculta de delphi 6
También un tutorial de sql, pero creo que con esos libros lo verás claro.

aguml 26-02-2017 01:42:12

El caso es que de los clientes solo tengo el nombre y, como mucho, el apellido ¿que ventaja tiene usar una tabla de clientes y otra de consumiciones si en ambas va a aparecer el nombre y apellido?. La verdad es que ese libro está muy bien para quien use Delphi pero para mi que no se nada de Delphi y casi nada de c++builder se hace demasiado técnico y se complica bastante seguirlo.

Casimiro Notevi 26-02-2017 01:49:10

La cara oculta de c++ builder, también :)

Es que como lo estás haciendo, no se hace. Ni tampoco hay que repetir datos en una tabla si lo tienes en otra.

aguml 26-02-2017 05:49:29

Ok gracias.

orodriguezca 27-02-2017 22:55:45

Aparte de tutoriales de SQL recomendaría también buscar algo de información sobre Normalización de Bases de Datos.

Casimiro Notevi 28-02-2017 11:56:30

Cita:

Empezado por orodriguezca (Mensaje 513778)
Aparte de tutoriales de SQL recomendaría también buscar algo de información sobre Normalización de Bases de Datos.

Totalmente.


La franja horaria es GMT +2. Ahora son las 17:00:04.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi