segunda-feira, 16 de maio de 2011

Retornar o mês por extenso, usando array

Nesta dica, vamos criar uma função para retornar o mês por extenso, somente informando o número do mês.

Programando:

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
function MesExtenso( Mes:Word ) : string;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function TForm1.MesExtenso( Mês:Word ) : string; const meses : array[0..11] of PChar = ('Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro','Outubro', 'Novembro', 'Dezembro');
begin
result := meses[mes-1];
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
label1.Caption := MesExtenso(3);
end;

end.

terça-feira, 10 de maio de 2011

Usando MessageBox

Para que as mensagens apareçam em portugues (na lingua no sistema) não é necessário a tradução das units.

Invés de usar a função messagedlg eh melhor usar a função MessageBox

Sintax:

MessageBox (Handle, Messagem, Caption, Botoes)
onde

Handle : Endereço do form na memória ; Sempre usu Application.Handle
Messagem : A messagem a ser mostrada
Caption : O titulo da messagem
Botoes : Os Botoes que irao ser mostrados. Na lingua do sistema

MB_ABORTRETRYIGNORE A messagem mostra os tres botoes: Abort, Retry, and Ignore.
MB_OK A messagem mostra um botoao: OK. This is the default.
MB_OKCANCEL A messagem mostra os dois botoes: OK and Cancel.
MB_RETRYCANCEL A messagem mostra os dois botoes: Retry and Cancel.
MB_YESNO A messagem mostra os dois botoes: Yes and No.
MB_YESNOCANCEL A messagem mostra os tres botoes: Yes, No, and Cancel.
Sons
MB_ICONEXCLAMATION, MB_ICONWARNING: Mostra o icone de exclamação e som conrrespondente. Analo aos demais
MB_ICONINFORMATION, MB_ICONASTERISK
MB_ICONQUESTION
MB_ICONSTOP,
MB_ICONERROR,
MB_ICONHAND
Botoes padrao
MB_DEFBUTTON1: Padrao nao precisa ser colocado.
MB_DEFBUTTON2: Coloca o segundo botao como padrao
MB_DEFBUTTON3: Coloca o terceiro botao como padrao
MB_DEFBUTTON4: Coloca o quarto botao como padrao
Respostas
IDABORT
IDCANCEL
IDIGNORE
IDNO
IDOK
IDRETRY
IDYES

Exemplo:

Case MessageBox (Application.Handle, Pchar ('Deseja excluir o arquivo' + #13 + Label1.caption), 'Exclusao de arquivo', MB_YESNOCANCEL+MB_EXCLAMATION+MB_DEFBUTTON2) of
idYes: Procedimento
idNo: Procedimento
idCancel: Procedimento
end;

O que fazer quando o StrToIntDef gera uma exceção

Quando utilizamos a função StrToInt e a string original não é um inteiro, o programa gera uma exceção. Para evitar isto, podemos utilizar a função StrToIntDef, que insere um valor predeterminado (default) caso a string não possa ser convertida em inteiro.

Veja o exemplo:

procedure TForm1.Button1Click(Sender: TObject);
var
    NumberString: string;
    Number: Integer;
begin
    NumberString := Edit1.Text;
    Number := StrToIntDef(NumberString, 1000);
    Edit2.Text := IntToStr(Number);
end;

Para que servem OnGetEditMask, OnGetEditText e OnSetEditText do TStringGrid

O evento OnGetEditMask ocorre quando entramos no modo de edição. Neste momento podemos verificar em qual linha/coluna se encontra o cursor e então, se quiser, poderá especificar uma máscara de edição. Exemplo:

procedure TForm1.StringGrid1GetEditMask(Sender: TObject; ACol, ARow: Integer; var Value: String);
begin
  if (ARow = 1) and (ACol = 1) then
  Value := '(999) 999-9999;1;_'; // Telefone
end;
O evento OnGetEditText ocorre também quando entramos no modo de edição. Neste momento podemos manipularmos o texto da célula atual (linha/coluna) e então podemos simular algo tal como uma tabela onde opções podem ser digitadas através de números. Exemplo:

procedure TForm1.StringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer; var Value: String);
begin
  if (ARow = 1) and (ACol = 2) then begin
  if StringGrid1.Cells[ACol, ARow] = 'Ótimo' then
  Value := '1'
  else if StringGrid1.Cells[ACol, ARow] = 'Regular' then
  Value := '2'
  else if StringGrid1.Cells[ACol, ARow] = 'Ruim' then
  Value := '3';
  end;
end;

O evento evento OnSetEditText ocorre quando saímos do modo de edição. Neste momento podemos manipular a entrada e trocar por um texto equivalente. Normalmente usamos este evento em conjunto com o evento OnGetEditText. Exemplo:

procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
begin
  if (ARow = 1) and (ACol = 2) then begin
  if Value = '1' then
  StringGrid1.Cells[ACol, ARow] := 'Ótimo'
  else if Value = '2' then
  StringGrid1.Cells[ACol, ARow] := 'Regular'
  else if Value = '3' then
  StringGrid1.Cells[ACol, ARow] := 'Ruim'
  end;
end;
Observações

Para testar o exemplo anterior crie um novo projeto e coloque no Form1 um TStringGrid. Mude os três eventos mencionados conforme os exemplos. Execute e experimente digitar nas céluas 1 e 2 da primeira linha (na parte não fixada).

domingo, 8 de maio de 2011

Tutorial para iniciante sobre JOIN's


Para aqueles que tinham dúvidas quanto ao funcionamento dos JOIN's das tabelas no SQL, desenvolvi um pequeno tutorial de apoio...
Tabelas e seus registros:

TABELA_A
Codigo
Nome
1
um
2
dois
3
três
4
quatro
5
cinco

TABELA B
Lanca
Codigo
Valor
1
1
1.000
2
1
2.000
3
1
5.000
4
2
4.000
5
2
9.000
6
3
7.000
7
5
4.000
8
8
7.000

Para a relação entre as tabelas temos:
3 registros para a empresa 1 (que existe na tabela de empresas);
2 registros para a empresa 2 (que existe na tabela de empresas);
1 registros para a empresa 3 (que existe na tabela de empresas);
0 registros para a empresa 4 (que existe na tabela de empresas);
1 registros para a empresa 5 (que existe na tabela de empresas);
1 registros para a empresa 8 (que NÃO existe na tabela de empresas);

Agora vamos ver como ficariam as pesquisas* (SELECT's) com os JOIN's ( INNER, [ LEFT | RIGHT | FULL ] OUTER ):


* Para tais pesquisas vamos usar a seguinte linguagem:

SELECT [CAMPOS]
FROM "TABELA_DA_ESQUERDA"
[INNER] JOIN | {LEFT | RIGHT | FULL } [OUTER]} JOIN "TABELA_DA_DIREITA"

1) INNER JOIN:

SELECT A.NOME "A.NOME",
B.VALOR "B.VALOR"
FROM TABELA_A A
INNER JOIN TABELA_B B ON B.CODIGO = A.CODIGO
 


A.NOME
B.VALOR
1
UM
1.000
2
UM
2.000
3
UM
5.000
4
DOIS
4.000
5
DOIS
9.000
6
TRÊS
7.000
7
CINCO
4.000


Nas pesquisas com INNER JOIN o resultado trará somente as linhas que sejam comum nas 2 tabelas, ligadas pelos campos das tabelas em questão na pesquisa.


2) LEFT OUTER JOIN:

SELECT A.NOME "A.NOME",
B.VALOR "B.VALOR"
FROM TABELA_A A
LEFT OUTER JOIN TABELA_B B ON B.CODIGO = A.CODIGO
 


A.NOME
B.VALOR
1
UM
1.000
2
UM
2.000
3
UM
5.000
4
DOIS
4.000
5
DOIS
9.000
6
TRÊS
7.000
7
QUATRO
NULL
8
CINCO
4.000

Nas pesquisas com LEFT OUTER JOIN o resultado trará todas os registros que estejam na tabela da esquerda do JOIN (neste caso é a TABELA_A) ao menos 1 vez, mesmo que não tenham registros na tabela da direita do JOIN (neste caso é a TABELA_B) ligadas à tabela da esquerda, como é o caso da linha 7.

3) RIGHT OUTER JOIN:
SELECT A.NOME "A.NOME",
B.VALOR "B.VALOR"
FROM TABELA_A A
RIGHT OUTER JOIN TABELA_B B ON B.CODIGO = A.CODIGO


A.NOME
B.VALOR
1
UM
1.000
2
UM
2.000
3
UM
5.000
4
DOIS
4.000
5
DOIS
9.000
6
TRÊS
7.000
7
CINCO
4.000
8
NULL
7.000

Nas pesquisas com RIGHT OUTER JOIN o resultado trará todas os registros que estejam na tabela da direita do JOIN (neste caso é a TABELA_B) ao menos 1 vez, mesmo que não tenham registros na tabela da esquerda do JOIN (neste caso é a TABELA_A) ligadas à tabela da direita, como é o caso da linha 8.

4) FULL OUTER JOIN:
SELECT A.NOME "A.NOME",
B.VALOR "B.VALOR"
FROM TABELA_A A
FULL OUTER JOIN TABELA_B B ON B.CODIGO = A.CODIGO


A.NOME
B.VALOR
1
UM
1.000
2
UM
2.000
3
UM
5.000
4
DOIS
4.000
5
DOIS
9.000
6
TRÊS
7.000
7
QUATRO
NULL
8
CINCO
4.000
9
NULL
7.000

Nas pesquisas com FULL OUTER JOIN o resultado trará todas os registros, ao menos 1 vez, que estejam nas 2 tabelas, tanto a da esquerda do JOIN (neste caso é a TABELA_A) quanto a da direita do JOIN (neste caso é a TABELA_B), como é o caso das linhas 7 e 9. O FULL poderíamos dizer que é uma junção entre o LEFT OUTER JOIN e o RIGHT OUTER JOIN.

domingo, 1 de maio de 2011

Armazanando sons, vídeos em bancos de dados

Um dos recursos mais interessantes nos bancos de dados atuais é a possibilidade de armazenar recursos multimídia juntamente com outras informações. Dessa forma, é possível criar registros com informações mais ricas sobre um determinado assunto. Por exemplo, pode-se armazenar informações sobre um funcionário juntamente com a sua própria foto. No Paradox, por exemplo, existe um tipo de campo destinado especialmente para esse fim.
No entanto, as possibilidades vão muito além do que o simples armazenamento de imagens. É possível armazenar sons, filmes ou qualquer tipo de arquivo, usando o "obscuro" campo BLOB (Binary Large Object), que permite que qualquer arquivo seja "embutido" no banco de dados. Na verdade, o conteúdo do arquivo não é armazenado no registro em si, mas num arquivo separado que é manipulado internamente pelo banco de dados.
Trabalhar com esse tipo de campo no Delphi é muito simples, mas não tão óbvio à primeira vista. A manipulação de campos BLOB, diferentemente dos campos comuns, não deve ser feita diretamente, mas sim por meio do objeto TBlobField, descendente do TField, que disponibiliza recursos especiais para esse fim. Para isso, você deve sempre se referir ao campo BLOB no código como sendo um TBlobField, utilizando typecasting.
Vamos supor que você tenha um arquivo de som MyWave.wav que será armazenado no campo "SOM" da tabela "MyTable". Para carregar o conteúdo do arquivo no campo SOM, basta fazer assim:
TBlobField(MyTable.FieldByName('SOM')).LoadFromFile('MeuWave.wav');
Neste exemplo, você usou o recurso de typecasting para manipular o campo como sendo um objeto TBlobField, carregando o arquivo através do método LoadFromFile que existe nesse objeto. Fácil, não é?
Se você quiser salvar o conteúdo do campo "SOM" no arquivo "MyWaveCopy.wav", basta fazer assim:
TBlobField(MyTable.FieldByName('SOM')).SaveToFile('MyWaveCopy.60wav');
Para remover o conteúdo do campo "SOM" (limpá-lo), você também deve usar um método apropriado:
TBlobField(MyTable.FieldByName('SOM')).Clear;
Para saber se o campo SOM possui algum conteúdo, use a propriedade IsNull:
with MyTable do
  if not TBlobField(FieldByName('SOM')).IsNull then
  TBlobField(FieldByName('SOM')).SaveToFile('MyWaveCopy.wav');
A maneira mais simples de utilizar o conteúdo de um campo BLOB já armazenado é primeiro gravá-lo novamente em um arquivo em disco, usando o método SaveToFile, e depois manipulá-lo normalmente. No caso de um conteúdo em formato wave, por exemplo, você deve primeiro gravá-lo num arquivo .wav, e então reproduzí-lo através do TMediaPlayer ou pela função SndPlaySound.
Usando os mesmos métodos, você também pode armazenar e manipular filmes AVI, apresentações, documentos, enfim, o que a sua imaginação mandar. Mas tenha em mente que o armazenamento de arquivos de som ou outros tipos vai aumentar consideravelmente o tamanho do seu banco de dados, por isso esse recurso deve ser utilizado com cuidado. Uma boa medida para reduzir esse problema é compactar o arquivo antes de armazená-lo. Para utilizá-lo depois, basta gerar o arquivo novamente em disco e descompactá-lo. Para saber quanto um campo BLOB está ocupando num registro do seu arquivo, em bytes, use a propriedade BlobSize:
TBlobField(MyTable.FieldByName('SOM')).BlobSize;
Obs: Para armazenar imagens ou texto em formato RichText (RTF), use os tipos GRAPHIC e FORMATED MEMO do Paradox, que são destinados a esses tipos de dados. O Delphi também possui objetos para a manipulação desses campos: TGraphicField e TMemoField, ambos descendentes do TBlobField.

sábado, 30 de abril de 2011

Acessando o banco de dados Oracle a partir do Delphi

Em vista de muitos hoje possuírem sistemas rodando com banco de dados Oracle, resolvemos publicar em detalhes todos passos necessários para se conectar a um banco Oracle a partir do Delphi de modo nativo (usando BDE) e através do ODBC. Temos observado também que dúvidas sobre este assunto estão sempre presentes nas listas de discussão sobre Delphi e sobre Oracle.

Utilizamos com bons resultados as versões do Delphi 2.0 até a 4.0, BDE versões 4.5 e 5.0, e o Oracle7 Workgroup Server Release 7.3.2.1. Naturalmente tais informações serão de grande ajuda para configuração em outras versões.

Passos:

1 - Caso tenha instalado em sua máquina algum cliente do Oracle 16 bits, poderá ter algum tipo de conflito com drives de 32 bits. Portanto, desinstale todos os clientes Oracle e instale somente o cliente Oracle 32 bits. Normalmente isto é feito a partir do CD de instalação do Oracle executando o programa d:\win95\install\setup.exe

2 - Ao executar o instalador do cliente Oracle para Windows 95, você deverá de inicio informar o idioma (o mesmo que foi informado durante a instalação do próprio banco), tendo o English como padrão.

3 - Entre com o nome da empresa e o diretório onde serão armazenados os arquivos do cliente Oracle.

4 - Será solicitado o tipo da instalação. Escolha a opção "Selective Products Install".

5 - Será apresentada uma lista dos produtos ou componentes disponíveis. Apesar de poder instalar todos, serão apenas necessários para a conexão com o banco Oracle a partir do Delphi os seguintes componentes:

Sql *Net Client (para criação do alias no cliente Oracle)

Oracle Installer (para instalar/remover componentes)

6 - Selecione os protocolos desejados para comunicação com o banco, ou poderá deixar selecionado a sugestão do instalador e prosseguir.

7 - Após completar 100% da instalação, você visualizará os componentes instalados:

Oracle Installer
Oracle Named Pipes Adapter (protocolo de acordo com sua rede)

Oracle SPX Adapter (protocolo de acordo com sua rede)

Oracle TCP/IP Adapter (protocolo de acordo com sua rede)

Required Support Files

Sql *Net Client

8 - Saia do instalador. Não será necessário reiniciar a máquina por enquanto.

9 - Clique no botão iniciar -> programas -> Oracle for windows 95 -> Sql Net Easy Configuration

10 - Selecione "Add Database Alias", e clique OK

11 - Informe na sequência:

Database Alias (nome na sua máquina que representará o acesso ao banco)

Escolha o Protocolo (normalmente TCP/IP)

TCP/IP Host Name (informe o numero IP do servidor Oracle)

Database Instance (nome da instância do banco, consulte o DBA)

12 - Clique em "yes" e saia do Sql Net Easy Configuration

13 - Chame o BDE Administrator, e clique na guia Configuration -> Drivers ->Native e selecione ORACLE. Como sugestão use as seguintes configurações:

VERSION
  4.0

TYPE
  SERVER

DLL32
  SQLORA32.DLL

VENDOR INIT
  ORA73.DLL

DRIVER FLAG
 (DEIXAR VAZIO)

TRACE MODE
  0

BATCH COUNT
  200

BLOB SIZE
  32

BLOBS TO CACHE
  64

ENABLE BCD
  FALSE

ENABLE INTEGERS
  FALSE

ENABLE SCHEMA CACHE
  FALSE

LANGDRIVER
  (DEIXAR VAZIO)

LIST SYNONYMS
  NONE

MAX ROWS
  –1

NET PROTOCOL
  TNS

OBJECT MODE
  TRUE

OPEN MODE
  READ/WRITE

ROWSET SIZE
 20

SCHEMA CACHE DIR
 (DEIXAR VAZIO)

SCHEMA CACHE SIZE
  8

SCHEMA CACHE TIME
  –1

SERVER NAME
  (COLOQUE O NOME DA INSTANCIA DO BANCO, DEFAULT: ORCL)

SQLPASSTHRU MODE SHARED
  AUTOCOMMIT

SQLQRYMODE
   SERVER

USER NAME
  (NOME DE USUARIO, OPCIONAL)

14 - Clique no item de menu Object -> Apply

15 - Agora precisamos apenas criar um Alias que será enxergado no Delphi. Para isso, clique na guia Database, clique com o botão direito do mouse sobre o item da lista ´Databases´ e selecione a opção ´New´. Escolha a opção ORACLE. Entre com o nome do Alias, que pode ser qualquer um que não exista. Agora altere do lado esquerdo na guia Definition, no item SERVER NAME, e coloque o nome do Database Alias que você criou no Sql Net Easy Configuration.

16 - Clique no item de menu Object -> Apply

17 - Reinicialize seu computador.

18 - Ok, agora basta abrir o Delphi e utilizar este Alias como qualquer outro!

Curso de Delphi: 7.Consultas SQL