Академический Документы
Профессиональный Документы
Культура Документы
Se trata del formulario donde podremos introducir la Serie y la Tabla para la que la utilizaremos, en
nuestro caso para la tabla "Factura". Los componentes de este formulario estarn enlazados con la
tabla "Serie" creada anteriormente.
Crearemos un formulario para la insercin y modificacin de los contadores:
Este formulario contendr los controles enlazados con la tabla "Contador" creada anteriormente.
Este formulario mostrar el contador (nmero) y la serie, ambos se generarn de forma automtica
desde el formulario de la factura. Desde este formulario podremos modifcarlos en caso necesario.
Crearemos un formulario para la insercin y modificacin de las facturas:
En este formulario ser donde utilicemos las series y el contador, a continuacin os mostramos el
cdigo fuente en Delphi del cdigo que insertaremos en el evento OnClick del botn
bGenerarNumFactura que es el que hay en la parte derecha del campo del nmero de factura. Este
botn generar el nmero de forma automtica segn la serie introducida en el campo anterior
(txtSerie):
procedure TformGFactura.bGenerarNumFacturaClick(Sender: TObject);
var
ano, mes, dia : word;
begin
if txtSerie.Text = '' then
begin
MessageDlg('La serie de la factura debe tener un valor.', mtWarning, [mbok], 0);
txtSerie.SetFocus;
end
else
begin
decodeDate(now, ano, mes, dia);
md.tFacturanumerofactura.AsString := llenarCadena(floattostr(generarNumeroSerie (
txtSerie.Text, vtTablaFactura)),6,'0', false) + '/' + inttostr(ano);
end;
end;
Donde:
txtSerie: es el TDBComboBox que contendr un desplegable con las series disponibles para
la tabla actual (Facturas).
md.tFactura: es el componente TTable enlazado con la tabla "Facturas", donde se guardan
los datos de la factura.
llenarCadena: es una funcin que rellena una cadena dada con el carcter indicado y con el
tamao indicado. A continuacin os mostramos el cdigo de esta funcin:
function llenarCadena ( cadena : string; numero : integer;caracter : Char;
derecha : Boolean) : string;
begin
while Length(cadena) < numero do
begin
if derecha then
cadena := cadena + caracter
else
cadena := caracter + cadena;
end;
llenarCadena := cadena;
end;
Esta funcin generar un nmero con el formato: 000032/2007.
generarNumeroSerie: esta funcin accede a la tabla "Contador" y obtiene el nmero por el que vaya
el contador segn la serie y la tabla que se le pase como parmetro. Tambin incrementa el contador
de esta tabla y serie. El cdigo de esta funcin es el siguiente:
function generarNumeroSerie (serie, tabla : string) : integer;
var
contador : integer;
begin
result := 1;
with md.tcContador do
begin
Close;
//obtenemos el contador de la tabla contadores
SQL.Clear;
SQL.Add('SELECT *');
SQL.Add('FROM ' + vtTablaContador);
SQL.Add('WHERE tabla = :pTabla and serie = :pSerie');
ParamByName('pTabla').DataType := ftString;
ParamByName('pTabla').AsString := tabla;
ParamByName('pSerie').DataType := ftString;
ParamByName('pSerie').AsString := serie;
Open;
if not (FieldByName('Contador').AsInteger = 0) then
begin
try
contador := FieldByName('contador').AsInteger + 1;
//Incrementamos el contador de la tabla contadores
Close;
SQL.Clear;
SQL.Add('UPDATE ' + vtTablaContador + ' SET contador = :pContador' +
' WHERE tabla = :pTabla' + ' and serie = :pSerie');
ParamByName('pContador').DataType := ftInteger;
ParamByName('pContador').AsInteger := contador;
ParamByName('pTabla').DataType := ftString;
ParamByName('pTabla').AsString := tabla;
ParamByName('pSerie').DataType := ftString;
ParamByName('pSerie').AsString := serie;
ExecSQL;
close;
result := contador;
except
Close;
result := 1;
MessageDlg ('El cdigo no ha podido ' + 'generarse automticamente.',mtError, [mbOK], 0);
end;
end
else
//si no existe el registro de contador para la tabla actual, lo creamos
begin
try
Close;
SQL.Clear;
SQL.Add('INSERT INTO ' + vtTablaContador + ' (tabla, serie, contador) ' +
' VALUES (:pTabla, :pSerie, 1)');
ParamByName('pTabla').DataType := ftString;
ParamByName('pTabla').AsString := tabla;
ParamByName('pSerie').DataType := ftString;
ParamByName('pSerie').AsString := serie;
ExecSQL;
result := 1;
Close;
except
Close;
MessageDlg ('El contador no se ha ' + 'guardado correctamente.',mtError, [mbOK], 0);
end;
end;
end;
end;
Donde:
md.tcContador: es el TTable enlazado con la tabla "Contador", donde se guarda un registro por
cada serie y factura con el nmero por el que vaya actualmente el contador. La aplicacin
funcionando tendr este aspecto:
Tercer paso:
Nuestra splash screen se debe crear antes de todos los dems form, y al terminar la carga de
las forms, esconderla y liberar su memoria
begin
SplashForm := TSplashForm.Create(Application);
SplashForm.Show;
SplashForm.Update;
Ahora tenemos que poner los forms que se deben cargar al inicio
Application.CreateForm(TForm1, Form1);
Antes que nuestra applicacin muestre la pantalla principal tenemos que, esconder la splash
screen y liberar su memoria
SplashForm.Hide;
SplashForm.Free;
Application.Run;
Finalizando:
Si compilamos veremos que nuestra splash screen no tiene tiempo de aparecer, si queremos
que se muestre unos segundos, agregamos la siguiente lnea antes de SplashForm.Hide
Sleep(2000);
Funcin Sleep es de la unidad SysUtils, para poderla utilizar debemos cargarla en uses del
proyecto
uses
Forms, Unit1 in Unit1.pas {Form1}, Unit2 in Unit2.pas {SplashForm}, SysUtils;
Ya podemos compilar y ver nuestra primera splash screen
Somente tabelas:
SELECT RDB$RELATION_NAME FROM RDB$RELATIONS
WHERE RDB$VIEW_BLR IS NULL;
Somente views:
SELECT RDB$RELATION_NAME FROM RDB$RELATIONS
WHERE NOT RDB$VIEW_BLR IS NULL;
Observao:
Para no incluir as tabelas e views de sistema, acrescente o filtro (RDB$SYSTEM_FLAG = 0 OR
RDB$SYSTEM_FLAG IS NULL) na clusula WHERE. Exemplo:
SELECT RDB$RELATION_NAME FROM RDB$RELATIONS
WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG = 0 OR RDB$SYSTEM_FLAG IS NULL);
Onde:
usuario: o nome de login do usurio (geralmente SYSDBA).
senha: a senha do usurio.
arquivo_banco: o arquivo de banco de dados (geralmente com extenso .gdb).
arquivo_backup: o arquivo de backup (geralmente com extenso .gbk).
Exemplo de backup:
gbak -b -user SYSDBA -password masterkey c:\sistema\dados.gdb c:\backup\dados.gbk
Exemplo de restore:
gbak -r -user SYSDBA -password masterkey c:\backup\dados.gbk c:\sistema\dados.gdb
Exemplos:
GEN_ID(Gen_Cliente_Codigo, 1);
GEN_ID(Gen_Cliente_Codigo, 0);
No primeiro exemplo o generator ser incrementado e o novo valor ser retornado. J no segundo exemplo o
generator no ser incrementado e seu valor atual ser retornado.
Dentro de um trigger podemos atribuir o valor de um generator a um campo da tabela, como mostra o
exemplo a seguir:
CREATE TRIGGER TRIG_Cliente_Inclusao FOR Cliente BEFORE INSERT AS
BEGIN
NEW.Codigo = GEN_ID(Gen_Cliente_Codigo, 1);
END^
Para obter o valor de um generator atravs de uma aplicao, podemos executar o comando SELECT
mostrado a seguir sobre uma tabela que possua apenas um registro:
SELECT GEN_ID(NomeDoGenerator, 1) FROM NomeTabela
Onde NomeTabela o nome de uma tabela do banco de dados que precisa ter um, e somente um, registro.
Geralmente usamos a tabela de sistema RDB$DATABASE para este propsito. Eis um exemplo:
SELECT GEN_ID(Gen_Cliente_Codigo, 1) FROM RDB$DATABASE;
Observao:
O valor obtido com GEN_ID(GEN_Cliente_Codigo, 1) aps o exemplo dado anteriormente ser 1 (um),
pois a funo GEN_ID retorna o valor do generator j incrementado.
Excluir generator
No InterBase 6.0.x:
DELETE FROM RDB$GENERATORS
WHERE RDB$GENERATOR_NAME = 'NOME_DO_GENERATOR';
No FireBird:
DROP GENERATOR NOME_DO_GENERATOR;
DOMAIN
DOMAIN
DOMAIN
DOMAIN
Comentrios:
O benefcio imediato do uso explcito de domnios a organizao do cdigo que define as tabelas.
Como um mesmo domnio ser usado em vrias tabelas (exemplo: DM_NomePessoa), ganharemos
muito tempo ao definir outras tabelas que comporo o banco de dados.
O domnio DM_Fone um exemplo que demonstra como um mesmo domnio pode ser usado para
colunas diferentes que possuem contedos semelhantes.
Os domnios DM_ChavePrimaria e DM_Renda mostram aspectos mais interessantes na declarao
de domnios, tais como a especificao de um valor padro (DEFAULT) e regras para validao
(CHECK).
Se mais tarde resolvermos alterar os nomes de pessoas para 50 caracteres, ou seja, VARCHAR(50),
bastar alterar a definio do domnio DM_NomePessoa e todos os campos definidos com este
domnio sero automaticamente ajustados. Neste caso bastaria o comando ALTER DOMAIN
DM_NomePessoa TYPE VARCHAR(50).
Nos bancos de dados que crio, uso domnios explicitamente para todos os campos de todas as tabelas,
mesmo onde aparentemente so desnecessrios. Mas bom lembrar que domnios mal definidos podem
trazer mais prejuzos do que benefcios. Portanto, antes de sair criando domnios deliberadamente, faa
um estudo minucioso do banco de dados a ser construdo.
Exemplos:
ALTER TABLE Cliente ALTER Nome TYPE VARCHAR(40);
ALTER TABLE Venda ALTER Total TYPE NUMERIC(18, 2);
Obs:
Em geral este comando no funciona se a troca de tipo implicar em perda de dados.
Sugesto:
Onde aparece NovoTipo voc poder usar um nome de domnio.
Exemplo:
ALTER TABLE Cliente ALTER Nome TYPE VARCHAR(50);
Obs:
Este comando no funciona se a alterao de tamanho implicar em perda de dados, ou seja, no serve para
reduzir o tamanho de um campo.
Sugesto
Use esta tcnica sempre que precisar transferir dados de um banco de dados para outro.
Observaes
A mesma coisa pode ser feita com triggers. No entanto importante lembrar que voc no deve atribuir
NULL, pois havia um bug no InterBase que fazia o trigger ser disparado duas vezes caso o cdigo-fonte
estivesse NULL. No sei se o bug foi corrigido. De qualquer forma, atribua uma string qualquer, tal como no
exemplo acima.
Observaes
Estes objetos com nomes iniciados com RDB$ so chamados de objetos de sistema e so usados internamente
pelo InterBase/FireBird. As tabelas comeadas com RDB$ contm dados sobre a estrutura do banco de
dados.
Onde:
banco = Caminho completo do banco de dados (arquivo .gdb).
senha = senha do sysdba.
Observaes
Voc tambm poder usar o IBConsole para alterar esta propriedade.
Observaes
Voc tambm poder alterar esta propriedade do banco de dados usando o IBConsole.
No ingresar 2 proposiciones
CaracteresValidos = [#1..#31, #8, 'p', 'q', 'r', 's', '<', '>', '(', ')', '^', '-'];
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (Key In CaracteresValidos) then
begin
Key := #0;
Beep;
end
else
if (key = anterior) then
begin
Key := #0;
Beep;
application.MESSAGEBOX('Imposible ingresar dos proposiciones consecutivas', 'Error!')
end
else
if anterior in CaracteresValidos then
begin
Key := #0;
Beep;
application.MESSAGEBOX('Imposible ingresar dos proposiciones consecutivas', 'Error!')
end
else
anterior := Key;
end;
begin
wDia := 24;
wMes := 8;
wAnyo := 2007;
IncAMonth( wAnyo, wMes, wDia );
Memo.Lines.Add( 'Da: ' + IntToStr( wDia ) );
Memo.Lines.Add( 'Mes: ' + IntToStr( wMes ) );
Memo.Lines.Add( 'Ao: ' + IntToStr( wAnyo ) );
end;
function IncWeek( const AValue: TDateTime; const ANumbe rOfWeeks: Integer = 1 ):
TDateTime;
Devuelve el valor fecha y hora AValue incrementando el nmero de semanas especificado en
ANumberOfWeeks (por defecto 1).
IncWeek( StrToDate( '24/08/2007' ) ) devuelve 31/08/2007
IncWeek( StrToDate( '24/08/2007' ), 2 ) devuelve 07/09/2007
function IncYear( const AValue: TDateTime; const ANumberOfYears: Integer = 1 ):
TDateTime;
Devuelve el valor fecha y hora AValue incrementando el nmero de aos especificado en
ANumberOfYears (por defecto 1).
IncYear( StrToDate( '24/08/2007' ) ) devuelve 24/08/2008
IncYear( StrToDate( '24/08/2007' ), 2 ) devuelve 24/08/2009
Bsqueda Incremental
Estoy haciendo una aplicacin y quiero que tenga Edit que sirva para buscar y
filtrar solamente el registro deseado.
procedure TFormPrincipal.Edit1Change(Sender: TObject);
begin
ClienDataSet1.Encomiendas_vista2.Filtered := False;
ClienDataSet1.Encomiendas_vista2.Filter := 'UPPER(Nombre) Like ' +
QuotedStr(UpperCase(Edit1.Text)+'%');
ClienDataSet1.Encomiendas_vista2.Filtered:= True;
end;
Con esto nos aseguramos hacer una bsqueda en blanco por cada criterio
elegido.
Consulta 1 Edit a 2 Columnas de una Tabla
Tengo una Tabla que entre varias columnas existen "Nombre" y "Apellido
Paterno", hasta ahora tengo la consulta para buscar o por nombre o por apellido y
funciona perfecto, la duda: existe la forma de poder "Filtrar" las 2 columnas segn
el criterio de 1 "Edit"???, en este caso algo as:
Nombre - Apellido
Juan - Tapia
Mara - Mora
Jos - Salas
La idea es que al escribir "1" queden en este caso filtrados la fila 1 y 2, ya que 1
tiene "1" en el apellido y 2 en el nombre.
Activamos el IBQuery.
Con un Filtro
MiTabla.Filter:='NIF ='+QuotedStr(Edit1.Text);
MiTabla.Filtered:=True;
Toma en cuenta que en este caso la cadena SQL que originalmente le asignaste a
la propiedad SelectSQL es reemplazada por cada nueva asignacin.
Datos del PC: Nombre, IP y usuario
Siempre es muy til poder disponer de los datos relativos a la red del equipo en el
que estamos ejecutando nuestra aplicacin. He englobado los principales datos en
una nica funcin para simplificar el proceso y as obtener:
- Nombre del PC
- Direccin IP local
- Nombre del usuario de Windows.
Recordad aadir al uses lo siguiente: WinInet, WinSock;
Para simplificar los parmetros he creado un tipo de datos que debis poner
despus del uses
type TDatosPC = record
Nombre, IP, Usuario :String;
end;
promedio
3.2
4.4
5.2
1.5
3.5
2.9
que necesito
digamos que
columna 2 se
de mi tabla:
FormB.Edit2.Text := DataSet.FieldByName('NombCliente').AsString;
FormSig.ShowModal;
end;
O si es una Table
Table.Filtered := False;
Table.Filter := 'nombre like '+QuotedStr(Edit1.Text+'%');
Table.Filtered := True;
- DBGrid de Prestamos
1 / 1500.00 / 25.00
ComboBox1.Items.Clear;
ComboBox1.Items.Add(DataSet['Salon']);
ComboBox1.Items.Add(DataSet['Materia1']);
ComboBox1.Items.Add(DataSet['Materia2']);
Salones
cod_curso *
materia1
ihs1
Calificaciones
cod_curso *
cod_alumno *
ao *
apellidos
ao
docente1
materia1
docente1
nota1p_mat1
logro1p_mat1
ausencia1_mat1
ao
cod_alumno
nombres
apellidos
materia1
docente1
nota1
logro1
Logro2
Logro3
En una base de datos (bien hecha) las tablas estn unidas gracias a sus llaves
primarias y forneas. Se navega desde una tabla A, tabla B y luego a la tabla C:
SELECT A.cod_alumno,S.cod_curso,A.nombre, (y todo lo dems)
FROM Alumnos A,Salones S, Calificaciones C
WHERE A.cod_alumno=C.cod_alumno AND C.cod_curso=S.cod_curso
ausencia
begin
if OpenPictureDialog.Execute then
begin
Jpg := nil;
Stream := nil;
try
Stream := TMemoryStream.Create;
FileExt := LowerCase(ExtractFileExt(OpenPictureDialog.FileName));
if (FileExt = '.bmp') or (FileExt = '.dib') then
begin
GraphType := gtBitmap;
Stream.Write(GraphType, 1);
with ImageFoto.Picture.Bitmap do
begin
LoadFromFile(OpenPictureDialog.FileName);
ImageFoto.Picture.Bitmap.SaveToStream(Stream);
end;
end
else if (FileExt = '.ico') then
begin
GraphType := gtIcon;
Stream.Write(GraphType, 1);
with ImageFoto.Picture.Icon do
begin
LoadFromFile(OpenPictureDialog.FileName);
ImageFoto.Picture.Bitmap.SaveToStream(Stream);
end;
end
else if (FileExt = '.emf') or (FileExt = '.wmf') then
begin
GraphType := gtMetafile;
Stream.Write(GraphType, 1);
with ImageFoto.Picture.Metafile do
begin
LoadFromFile(OpenPictureDialog.FileName);
ImageFoto.Picture.Bitmap.SaveToStream(Stream);
end;
end
else if (FileExt = '.jpg') or (FileExt = '.jpeg') or (FileExt = '.jpe') then
begin
Jpg := TJpegImage.Create;
Jpg.LoadFromFile(OpenPictureDialog.FileName);
ImageFoto.Picture.Assign(Jpg);
GraphType := gtJpeg;
Stream.Write(GraphType, 1);
Jpg.SaveToStream(Stream);
end;
DataModule1.IBTPersonas.Edit;
Stream.Position := 0;
DataModule1.IBTPersonasFoto.LoadFromStream(Stream);
except
jpg.Free;
Stream.Free;
raise;
end;
jpg.Free;
Stream.Free;
end;
end;
clave,
id_perfil
FROM
usuarios
WHERE
clave=:
cla
AND
de cliente y cobrador debe mostrar sus nombres, para eso deber tomar el cdigo
de caja y localizar en las otras 2 tablas sus nombres.
SELECT
a.idcaja, b.cliente, c.colaborador
FROM cajas AS a
INNER JOIN clientes AS b
ON b.idcliente = a.clienteid
INNER JOIN colaboradores AS c
ON c.idcolaborador = a.colaboradorid
Id
1
2
3
4
5
Idint
1
1
2
2
2
FechaBaja
01/08/2013
30/07/2013
25/05/2013
Consulta necesaria
Yo tengo una tabla cargada con varios datos, supongamos movimientos de un
expediente, dentro de los datos importantes en cada registro est el No. de
expediente (o cdigo nico) y el orden en que se realiz el paso.
No.
1001
1001
1001
1002
1002
1005
1005
1005
1005
Orden
1
2
3
1
2
1
2
3
4
(que son los que estn vacos en apellido1) y que la tabla quedara as:
1
2
3
4
Si lo has hecho as te quedara que todos los que tengan el apellido2 vaco
tambin tengan vaco el apellido1 y por si acaso no estaba suficientemente vaco
el apellido2 lo vuelves a vaciar. Creo que sera algo como
UPDATE corredores SET apellido1=apellido2,apellido2=''
WHERE apellido1 IS NULL
Supongo que con algo as funcionara dando por hecho que realizar la primera
actualizacin antes que la segunda.
Tambin podra hacer la comprobacin a la hora de volcar los datos a la tabla
Firebird, no s cmo haces el traspaso de un lado a otro pero doy por sentado que
en algn momento podras meter la comprobacin.
Por ltimo podras hacer que al buscar por apellido no hagas dos campos de
bsqueda, uno para el apellido1 y otro para el apellido2, yo pondra un solo campo
que sera apellido y luego buscara en la tabla coincidencias en los dos campos.
SELECT * FROM corredores
WHERE apellido1 LIKE '%ernandez%' OR apellido2 LIKE '%ernandez%'
QAcceso.ExecSQL;
ShowMessage('Informacion grabada satisfactoriamente');
end;
txtEQ_SO.Items.Add(' ');
Con esto debera incrementar la lista de lo que hay en el ComboBox, dentro de los
parntesis de este pones lo que vas a adherir al combo.
Otra idea: Que te parece, borras lo que tienes en el ComboBox y realizas la
consulta por medio de un Query y lo agregas al combo as:
ComboBox.Items.Clear;
With IBQuery do
begin
Close;
Sql.Clear;
Sql.Add('SELECT campo FROM tabla');
Open; First;
If Not IsEmpty Then
begin
While Not EOF do
begin
ComboBox.Items.Add(FieldByName('campo').AsString);
Next;
end;
end;
end;
Consulta en Firebird
Tengo una tabla personas y otra personas-operaciones Firebird personas (idnombre) personas-operaciones (idpersona-tipooperacion-lugar-descripcion).
Como se puede realizar un SELECT, que muestre todas las personas que
coincidan independientemente de cuantas lneas como parmetro quiera
introducir.
SELECT DISTINCT...
FROM INNER JOIN...
WHERE
AND
personas-operacion.lugar =: lugar
AND
personas-operacion.descripcion =: descripcin
CODIGO
2
2
3
3
3
4
AO
2009
2010
2008
2009
2010
2010
VECES
2
3
1
Ese sera la clusula SQL. Lo importante aqu es el GROUP BY, que se utiliza
para agrupar registros y con la combinacin de la funcin COUNT, obtienes lo que
deseas.
Direccin
Colonia Madero #222
Observar que el orden del valor del registro puede ser distinto al criterio que
busco, pero debe mostrarme primero los registros que mayor coincidencia tenga.
No, no existe nada similar para Firebird, pero te puedes construir una consulta,
parecida a la que proponas inicialmente, en la que adems calculas el nmero de
coincidencias sobre las palabras buscadas, y ordenas de mayor a menor en
funcin de esas coincidencias. Por ejemplo., para buscar por 3 palabras:
SELECT dir,
(CASE WHEN dir CONTAINING :txt1 THEN 1 ELSE 0 END +
CASE WHEN dir CONTAINING :txt2 THEN 1 ELSE 0 END +
CASE WHEN dir CONTAINING :txt2 THEN 1 ELSE 0 END) AS coincidencias
FROM clientes
WHERE dir CONTAINING :txt1 OR
dir CONTAINING :txt2 OR
dir CONTAINING :txt3
ORDER BY coincidencias DESCENDING
Consulta filtrada
Tengo problemas al querer filtrar una consulta en Firebird
Datos en tabla:
COD1
COD2
01
001
01
002
02
001
03
001
01
003
REG_ID
1
2
3
4
5
Si quieres poner los valores uno debajo de otro, tenis que incrementar el ndice
de las filas y dejar fijo el de las columnas, por ejemplo:
with StringGrid1 do
begin
Cells[Col, FixedRows ]:= Edit1.Text;
Cells[Col, FixedRows+1]:= Edit2.Text;
Cells[Col, FixedRows+2]:= Edit3.Text;
end;
//Billetes de 20
if cb20.Checked then
begin
Desglose:=Int(Dinero / 20);
Dinero:=Dinero - Desglose * 20;
Billetes[2]:=Billetes[2] + Desglose;
end;
//Billetes de 10
if cb10.Checked then
begin
Desglose:=Int(Dinero / 10);
Dinero:=Dinero - Desglose * 10;
Billetes[3]:=Billetes[3] + Desglose;
end;
//Billetes de 5
if cb05.Checked then
begin
Desglose:=Int(Dinero / 5);
Dinero:=Dinero - Desglose * 5;
Billetes[4]:=Billetes[4] + Desglose;
end;
//Billetes de 3
if cb03.Checked then
begin
Desglose:=Int(Dinero / 3);
Dinero:=Dinero - Desglose * 3;
Billetes[5]:=Billetes[5] + Desglose;
end;
//Billetes de 1
Desglose:=Int(Dinero / 1);
Dinero:=Dinero - Desglose * 1;
Billetes[6]:=Billetes[6] + Desglose;
//****************************** Monedas ******************************
Dinero:=(Round((Frac(Importe)*100)));
//Monedas de 0.20
if cb020.Checked then
begin
Desglose:=Int(Dinero / 20);
Dinero:=Dinero - Desglose * 20;
Monedas[0]:=Monedas[0] + Desglose;
end;
//Monedas de 0.05
if cb005.Checked then
begin
Desglose:=Int(Dinero / 5);
Dinero:=Dinero - Desglose * 5;
Monedas[1]:=Monedas[1] + Desglose;
end;
//Monedas de 0.02
if cb002.Checked then
begin
Desglose:=Int(Dinero / 2);
Dinero:=Dinero - Desglose * 2;
Monedas[2]:=Monedas[2] + Desglose;
end;
//Monedas de 0.01
Desglose:=Int(Dinero / 1);
Dinero:=Dinero - Desglose * 1;
Monedas[3]:=Monedas[3] + Desglose;
end;
1 100 123456789
1 500 965432178
1 400 111118888
1 200 598444444
NOMBRE_CIUDAD
Villa Carlos Paz
Federacin
Coronel Vidal
Gonzlez Chvez
PROVINCIA_ID
5
12
3
3
Tabla PROVINCIAS:
ID
3
12
5
NOMBRE_PROVINCIA
Buenos Aires
Entre Ros
Crdoba
Crdoba
Entre Ros
Buenos Aires
Buenos Aires
5
12
3
3
Solicitudes
Integer
VarChar
Id_Solicitud
Id_Prestador
Terminada
Integer
Integer*
VarChar
Total_Solicitudes_Prestador
10
20
5
Terminada_Si
5
10
3
Terminada_N
4
8
1
Terminada_No_Aplica
1
2
1
SELECT Id_Prestador,
SUM(Terminada) AS TotalTerminada,
SUM(NoTerminada) AS TotalNoTerminada,
SUM(NoAplica) AS TotalNoAplica
FROM (SELECT ID_Prestador,
IIF(Terminada = 'SI', 1, 0) AS Terminada,
IIF(Terminada = 'NO', 1, 0) AS NoTerminada,
IIF(Terminada = 'NO APLICA', 1, 0) AS NoAplica
FROM Solictudes) GROUP BY Id_Prestador
Imgenes en Firebird
Estoy diseando una aplicacin relacionada con el control de personal, el tema es
que el cliente ha solicitado que entre toda la informacin est contenida la foto de
cada trabajador.
En este caso no se utiliza otro campo para el formato. Para probar en un
Formulario (Form1) pones:
if OpenPictureDialog.Execute then
begin
Jpg := nil;
Stream := nil;
try
Stream := TMemoryStream.Create;
FileExt := LowerCase(ExtractFileExt(OpenPictureDialog.FileName));
if (FileExt = '.bmp') or (FileExt = '.dib') then
begin
GraphType := gtBitmap;
Stream.Write(GraphType, 1);
with ImageFoto.Picture.Bitmap do
begin
LoadFromFile(OpenPictureDialog.FileName);
ImageFoto.Picture.Bitmap.SaveToStream(Stream);
end;
end
else if (FileExt = '.ico') then
begin
GraphType := gtIcon;
Stream.Write(GraphType, 1);
with ImageFoto.Picture.Icon do
begin
LoadFromFile(OpenPictureDialog.FileName);
ImageFoto.Picture.Bitmap.SaveToStream(Stream);
end;
end
else if (FileExt = '.emf') or (FileExt = '.wmf') then
begin
GraphType := gtMetafile;
Stream.Write(GraphType, 1);
with ImageFoto.Picture.Metafile do
begin
LoadFromFile(OpenPictureDialog.FileName);
ImageFoto.Picture.Bitmap.SaveToStream(Stream);
end;
end
else if (FileExt = '.jpg') or (FileExt = '.jpeg') or (FileExt = '.jpe') then
begin
Jpg := TJpegImage.Create;
Jpg.LoadFromFile(OpenPictureDialog.FileName);
ImageFoto.Picture.Assign(Jpg);
GraphType := gtJpeg;
Stream.Write(GraphType, 1);
Jpg.SaveToStream(Stream);
end;
DataModule1.IBTPersonas.Edit;
Stream.Position := 0;
DataModule1.IBTPersonasFoto.LoadFromStream(Stream);
except
jpg.Free;
Stream.Free;
raise;
end;
jpg.Free;
Stream.Free;
end;
end;
Controlar DBLookupComboBox
Cargo un DBLookupComboBox desde la BD sin problemas, en la lista tenemos
varios tems, cuando el usuario selecciona un elemento de la lista, el sistema se
detiene y le pregunta si est seguro de cambiar de tem, esto se hace porque si el
tipo responde que "si" algunas cosas del formulario cambian; y si responde que
"no" el formulario no debera cambiar y el elemento visible en el combo tampoco
debera cambiar al que seleccion.
Resulta que si respondo que "si", no hay problema, pero cuando respondo que no,
los cambios en el formulario no se hacen pero el elemento visible cambia, y yo no
quiero que cambie. Lo que necesito es que cuando responda que "no" el combo
ponga visible la opcin que estaba antes de hacer clic en l.
var
OldKeyValue: string;
procedure TForm1.DBLookupComboBox1Enter(Sender: TObject);
begin
OldKeyValue:= VarToStr(DBLookupComboBox1.KeyValue);
end;
procedure TForm1.DBLookupComboBox1Click(Sender: TObject);
begin
if MessageBox(Handle,' Desea cambiar de tem?',
'',MB_ICONQUESTION+MB_YESNO) = IDNO then
DBLookupComboBox1.KeyValue:= OldKeyValue
else
OldKeyValue:= VarToStr(DBLookupComboBox1.KeyValue);
end;
end;
Ejemplo: Si tengo una tabla con el campo1 tipo Integer y con estos datos.
Campo1 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Como podra buscar u obtener la tabla ordenada por el criterio de proximidad a un
valor, por ejemplo del 5:
Campo1= 4, 6, 7, 3, 8, 2, 9, 1, 10
Select campo1,
Case When (campo1 - :valor) > 0 Then campo1 :valor Else -1 * (campo1 - :valor)
From tabla
Order By 2
Agregar Nombre a las columnas de Un TDBGrid en Tiempo de Ejecucin
No encuentro la manera de agregar nombre a las columnas de un TDBGrid en
tiempo de ejecucin.
procedure TForm1.Button1Click(Sender: TObject);
begin
TDBGrid1.Columns[1].Title.Caption:='Clientes';
end;
Agrupar datos
Tengo una tabla de devoluciones al Almacn y esta es su detalle, en la consulta que
necesito, quiero agrupar los artculos que tengan la misma caracterstica en cuanto a
Nombre, Largo y Ancho.
Folio
1.1
2.1
2.2
3.1
4.1
4.2
4.3
Nombre
Cartulina doble
Cartulina doble
Jac Cromo
Laminado
Couche
Laminado
Jac Cromo
Cantidad
5
7
5
2
7
2
9
Largo
1200
1200
1000
1000
1500
1000
1000
Ancho
0.140
0.140
0.110
0.120
0.150
0.120
0.110
Fecha
02/06/03
03/06/03
03/06/03
09/06/03
01/07/03
01/07/03
01/07/03
Debemos asignar Type: String; Nombre del Parmetro, y su valor Unknown, luego
en cdigo podemos hacer referencia a l a travs de QueryX.Params[0] asignndole
el valor actual. Previo a esto debemos:
Query.Close;
Query.Clear;
Params[0].Value:=XXX;
Query.SQL.Add('Select campos From table Where campo
= :XXX');
Query.Open;
Cerrar
Limpiar
Asignar el parmetro
Estamento SQL
Abrir
with IBQuery1 do
begin
Close;
ParamByName('pname').AsString := Edit1.Text;
Open;
end;
De otro modo, si consulta y parmetro son creados en tiempo de ejecucin, se
deben especificar ambos, mediante la propiedad vectorial Params:
with IBQuery1 do
begin
Close;
SQL.Text := 'Select * From tabla Where name = :pname';
Params[0].AsString := Edit1.Text;
Open;
end;
Mediante el mtodo ParamByName:
with IBQuery1 do
begin
Close;
SQL.Text := 'Select * From tabla Where name = :pname';
ParamByName('pname').AsString := Edit1.Text;
Open;
end;
Y es mediante la propiedad ParamValue:
with IBQuery1 do
begin
Close;
SQL.Text := 'Select * From tabla Where name = :pname';
Params.ParamValues['pname'] := Edit1.Text;
Open;
end;
Por ltimo cabe acotar que si existe una definicin de consulta/parmetros en tiempo
de diseo, al asignar una nueva definicin de consulta/parmetros en tiempo de
ejecucin, se sobrescribir lo realizado en tiempo de diseo.
En Columns Editor.... mostrado, hacer clic con el botn derecho y elija la opcin Add
All Fields, o pulsa el botn rodeado en rojo mostrado en la imagen.
end;
First;
end;
Timer1.Interval := 3000;
Timer1.Enabled := True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
i: Integer;
begin
Timer1.Enabled := False;
with ClientDataSet1 do
begin
DisableControls;
try
First;
for i:= 1 to MAX do
begin
Edit;
FieldByName('OR_TIPO').AsInteger := Random(5)+1;
Next;
end;
First;
finally
EnableControls;
end;
end;
Timer1.Enabled := True;
end;
procedure TForm1.TDBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
C : TColor;
begin
with Sender as TTDBGrid do
begin
case ClientDataSet1.FieldByName('OR_TIPO').AsInteger of
1: C:= clLime;
2: C:= clYellow;
3: C:= clMoneyGreen;
4: C:= clRed;
5: C:= clAqua;
end;
Canvas.Brush.Color := C;
Modelo
1528
1180
1528
Tabla Cdigos
ID_Codigo ID_Camion Cdigo
1
1
23
40
Lectura
3400
3600
3350
1500
1600
1250
1000
0950
1000
1250
Fecha
01/01/2008
01/02/2008
31/12/2007
01/01/2008
01/02/2008
31/12/2007
31/12/2007
01/11/2007
01/11/2007
31/12/2007
Se necesita hacer una consulta que genere la salida, suministrando como parmetro
fecha1 y fecha2: Parmetros:
fecha1: 01/01/2008 - fecha2: 01/02/2008
Consumo
200
10
begin
nfi= fi;
nff= ff;
/* Adecuamos la fecha y hora de inicio respecto al fin del horario */
if (Cast(nfi As Time) > hfh) then
nfi= Cast(nfi+1 As Date) + hih;
/* Adecuamos la fecha y hora de inicio respecto al inicio del horario */
if (Cast(nfi As Time) < hih) then
nfi= Cast(nfi As Date) + hih;
/* Adecuamos la fecha y hora de inicio respecto a los fines de semana */
if (Extract(WeekDay From nfi) = 6) then /* Sabados*/
nfi= Cast(nfi+2 As Date)+ hih;
if (Extract(WeekDay From nfi) = 0) then /* Domingos*/
nfi= Cast(nfi+1 As Date)+ hih;
/* Adecuamos la fecha y hora de fin respecto al fin del horario */
if (Cast(nff As Time)> hfh) then
nff= Cast(nff As Date)+hfh;
/* Adecuamos la fecha y hora de fin respecto al inicio del horario */
if ( Cast(nff As Time) < hih) then
nff= Cast(nff-1 As Date)+hfh;
/* Adecuamos la fecha y hora de fin respecto a los fines de semana */
if (Extract(WeekDay From nff) = 6) then /* Sabados */
nff= Cast(nff-1 As Date)+ hfh;
if (Extract(WeekDay From nff) = 0) then /* Domingos*/
nff= Cast(nff-2 As Date)+ hfh;
/* Calculamos los das de fin de semana */
syd =((DatedIff(Day, nfi, nff)+Extract(WeekDay From nfi) )/7) *2;
/* Calculamos todos los das sin fines de semana. Hay que quitarle un da... */
tw = DatedIff( Day, nfi, nff) -1 - syd;
if (tw < 0) then
tw=0;
tff = tw;
-- Das transcurrido * horasDia + horas de primer da + horas del ultimo da
taf = tw * DatedIff( Minute ,hih, hfh) /60.00 +
DatedIff(Minute, Cast(nfi As Time), hfh)/60.00 +
DatedIff(Minute, hih, Cast(nff As Time))/60.00 ;
/* Quitamos los fes sin incluir los das de inicio y fin, que tratamos luego */
CServ
Importe ImporteTotal
Cambio de llantas $700.00
$700.00
Cambio de balatas $800.00
$1500.00
Cambio de aceite
$100.00
$100.00
Necesitara poder sacar los datos agrupados por id_arbitre pero el problema es que
el valor de este ID, puede estar en cualquiera de las 8 columnas posibles.
Vamos que lo que necesitara es poder sacar todos los registros donde aparezca por
ejemplo el valor del rbitro 1, algo as: y sucesivamente, para sacar una hoja por
cada rbitro.
Arbitro 1
Recibo 1
Recibo 3
Recibo 5
Arbitro 2
Recibo 1
Recibo 2
Recibo 3
El problema que tengo y que no s cmo solventar es que el valor del id_arbitre = 1
puede estar tanto en id_arbitre_1, id_arbitre_2, id_arbitre_3, id_arbitre_4,
ID_arbitre_5, id_arbitre_6, id_arbitre_7, id_arbitre_8, pero solo una vez en cada
recibo. Luego todos los campos adicionales son los que tienen el mismo numero
id_arbitre_1 -> km_1 -> total_1, etc.
Select id_arbit1, id_rebut, import_1, sobres_1,
dos_sectors1, total_a1 From re0010dg
Where id_arbit1 = 1
UNION
Select id_arbit2, id_rebut, import_2, sobres_2,
dos_sectors2, total_a2 From re0010dg
Where id_arbit2 = 1
UNION
Select id_arbit3, id_rebut, import_3, sobres_3,
dos_sectors3, total_a3 From re0010dg
Where id_arbit3 = 1
UNION
Select id_arbit4, id_rebut, import_4, sobres_4,
dos_sectors4, total_a4 From re0010dg
Where id_arbit4 = 1
UNION
Select id_arbit5, id_rebut, import_5, sobres_5,
dos_sectors5, total_a5 From re0010dg
Where id_arbit5 = 1
UNION
Select id_arbit6, id_rebut, import_6, sobres_6,
dos_sectors6, total_a6 From re0010dg
Where id_arbit6 = 1
UNION
Select id_arbit7, id_rebut, import_7, sobres_7,
dos_sectors7, total_a7 From re0010dg
Where id_arbit7 = 1
UNION
Josep
Lio
Johnny
Antonio
Fernndez
Chin
Walker
Gmez
Albert
Prez
etc.
etc.
etc.
etc.
Lo que yo necesitara sera que una vez importados los datos a la tabla, pudiera
recorrer la tabla y cambiar el valor de los registros 2 y 3 (que son los que estn
vacos en apellido1) y que la tabla quedara as:
1
2
3
4
Josep
Lio
Johnny
Antonio
Fernndez
Chin
Walker
Gmez
Albert
Prez
etc.
etc.
etc.
etc.
Actualizacin:
Update corredores Set apellido1=apellido2, apellido2='' Where apellido1 Is Null
Bsqueda:
Select * From corredores Where apellido1 Like '%ernandez%' Or apellido2 Like
'%ernandez%'
Editar Informacin de DBEdit y tambin en DBGrid
Tengo una pequea tabla de prctica, creada de la siguiente manera.
CREATE TABLE USUARIO (
CODIGO CHAR(12) NOT NULL,
NOMBRE CHAR(30),
APELLIDO CHAR(30),
CIUDAD CHAR(20),
TELEFONO CHAR(12)
);
Luego hicimos las conexiones a una forma, usando IBX, como se necesita, usando
un TIBDataSet y unos DBEdit, conectamos la base de datos y un DBGrid usando un
DataSource.
Usando un IBQuery, hacemos una bsqueda en la tabla para buscar la informacin
que ha sido digitada en el DBEdit. Cuando la informacin se encuentra en la tabla
esta se debe poder Editar, y adicionalmente debo poder ver la informacin en el
DBGrid.
Como la informacin me la entrega un IBQuery, esta solo se puede mirar, pero no se
puede entrar a editar en los otros DBEdit, debido a que los DBEdit no estn mirando
la tabla, sino la informacin del IBQuery, y mucho menos apuntando en el DBGrid.
Creo que te va a resultar ms simple utilizar el evento OnSetText del TField en
cuestin:
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure CampoSetText(Sender: TField; const Text: String);
public
end;
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
IBDataSet1.FieldByName('CAMPO_BUSQUEDA').OnSetText:= CampoSetText;
end;
procedure TForm1.CampoSetText(Sender: TField; const Text: String);
begin
if not IBDataSet1.Locate('CAMPO_BUSQUEDA', Text, []) then
Abort;
end;
En el ejemplo asigno el evento en tiempo de ejecucin; pero si tienes creados los
campos persistentes lo podes hacer en diseo desde el Object Inspector.
Consulta para insertar campo en una tabla si no existe
Buscando la manera de insertar un campo en una tabla pero verificando que ste no
existiera previamente a travs de un SP:
CREATE OR ALTER PROCEDURE InsertarCampo
AS
begin
if (Not Exists(select 1 From RDB$Relation_Fields
Where RDB$Relation_Name = 'tabla' And RDB$Field_Name = 'CAMPO')) then
Execute Statement 'Alter Table tabla Add campo Integer';
end;
Problemas con Update
Tengo dos tablas, clientes y repartidores, y necesito hacer un Update en un campo
de la tabla clientes cuando se cumpla la condicin clientes.cod = repartidores.cod.
El problema viene cuando quiero darle el valor a pelo, no el de un campo de la tabla,
sino hara un Select sobre el campo y le dara el valor.
CREATE TABLE "CLIENTES" (
COD VARCHAR(20) NOT NULL,
TRC CHAR(1) NOT NULL
);
CREATE TABLE "REPARTIDORES" (
COD VARCHAR(20) NOT NULL
);
Update clientes c Set c.trc = 's' Where c.cod In (Select "cod" From repartidores)
tablas,