SlideShare a Scribd company logo
ce nade p.o rg

http://www.cenadep.o rg/2013/11/18/peno mo ran-transaksi-o to matis-dengan-delphi-mysql/

Penomoran Transaksi Otomatis Dengan Delphi & MySQL
Dalam tulisan kali ini kita akan membuat sebuah contoh penomoran otomatis dengan database MySQL
untuk berbagai macam transaksi dalam aplikasi.
Sebelum melanjutkan, kita lihat dulu seperti apa penomoran yang akan kita buat.
Penomoran dalam contoh ini memiliki kriteria sebagai berikut:
Menyertakan kode unit, yaitu kode unit kerja yang bertransaksi. Ini bermanf aat untuk aplikasi yang
memiliki f itur multi-unit atau cabang perusahaan.
Menyertakan kode transaksi, untuk memudahkan pengenalan nomor transaksi. Misalnya JU untuk
Jurnal Umum, KM untuk Kas Masuk, PO untuk Purchase Order, RB untuk Retur Pembelian, SO untuk
Stock Opname, dsb.
Menyertakan tanggal transaksi
Menyertakan nomor urut per tanggal transaksi, direset ke 1 apabila tanggak berganti.
Dari kriteria di atas, ini contoh nomor transaksinya:
101PO-20131118-00006
Di mana:
101 adalah kode unit kerja. Saya anggap bahwa kode unit kerja adalah 001 sampai 999 (varchar [3]).
PO- adalah pref ix transaksi (jenis transaksi). Dalam hal ini, PO- berarti Purchase Order (Pembelian).
20131118 adalah tanggal transaksi
00006 adalah nomor urut transaksi harian. Dalam contoh, nomor di atas adalah nomor transaksi
Purchase Order yang keenam dalam tanggal 18 November 2013.
Panjang nomor di atas adalah 20 karakter. Angka 20 ini harus baku, tidak boleh diubah, agar tidak merusak
f ormat/pemotongan kode-kode dalam nomor sesuai kriteria. Bila Anda ingin membuat nomor sendiri yang
panjangnya dinamis, cara dalam tulisan ini tidak dapat dipakai begitu saja melainkan memerlukan modif ikasi.
Dalam tulisan ini kita anggap bahwa panjang kode unit cukup 3 karakter, panjang pref ix transaksi (jenis
transaksi) 3 karakter: dalam contoh, terdiri dari dua huruf jenis transaksi dan satu huruf pemisah “-”.
Sedangkan panjang nomor urut adalah 5 karakter dan memuat sampai 99.999 transaksi per hari untuk tiap
jenis transaksi.
Penomoran ini akan disimpan dan diupdate ke database sehingga dapat dipakai oleh multi-client. Anggap
ada dua klien yang terhubung ke server, yang satu mendapatkan nomor urut 101PO-20131118-00006
sedangkan klien lainnya mendapatkan nomor urut 101PO-20131118-00007 secara otomatis sehingga
menjamin keunikan nomor transaksi. Bila nomor ini disimpan di klien, bisa terjadi tabrakan apabila ada nomor
yang sama dari klien yang berbeda. Selanjutnya bila nomor tetap disimpan di database tapi digenerate di
aplikasi (klien) tentu akan memperlambat sistem, karena ada pertukaran data yang tidak perlu antara sever
dan klien.
Persiapan Database Dan Tabel
Kembali saya ingatkan, nomor dan kriterianya akan disimpan dalam database. Karenanya kita perlu sebuah
database dan sebuah tabel untuk menampung nomor-nomor transaksi yang digenerate.
Pertama, kita buat sebuah database baru di MySQL. Untuk mempermudah interaksi dengan MySQL server,
saya sarankan untuk menggunakan HeidiSQL, antarmuka GUI gratis untuk MySQL.
Loginlah ke MySQL dan buat sebuah database baru dengan nama tes_penomoran_otomatis.
Selanjutnya buatlah sebuah tabel dengan nama
sys_options yang berisi dua f ield: optname dan
optvalue. Tabel ini akan digunakan untuk menampung
variabel dan nilainya. Dalam contoh penomoran
otomatis dengan Delphi dan MySQL ini, kita akan
menampung variabel [nama_nomor] dan
[nilai_nomor_terakhir]. Setiap saat kita perlu
menggenerate nomor baru, tabel ini akan diupdate:
record dengan [nama_nomor] yang sesuai akan diambil
nilainya, diupdate (bertambah 1), disave kembali ke
database dan nilai hasil update akan dikembalikan ke
user. Bila [nama_nomor] ini masih kosong
(f ield [nilai_nomor_terakhir] masih kosong), akan
dibuat yang baru berisi nilai nomor pertama dengan
nomor urut 00001.
Secara pseudo (gambaran), proses generate dan update nomor otomatis ini dapat dilihat pada diagram
berikut:

Kembali ke tabel sys_options tadi, silahkan gunakan kode berikut untuk membuatnya:
0001
0002
0003
0004
0005

CREATE TABLE `sys_opt ions` (
`opt name`VARCHAR(50)NOT NULL,
`opt value` TINYTEXTNULL,
PRIMARY KEY (`opt name`)
);

Selain bermanf aat untuk menampung nomor otomatis, tabel ini juga dapat digunakan untuk menampung
data lainnya, misalnya user yang terakhir login, setting printer/kertas, dsb.
Menggunakan Stored Function
Karena proses generate dilakukan dalam database dan melibatkan proses update, insert atau delete, kita
akan menggunakan stored f unction untuk mempermudah pekerjaan menggenerate dan update nomor pada
tabel sys_options…
Kita membutuhkan 3 buah stored f unction dalam hal ini: set_option(name, value), get_option(name),
gen_nomor_otomatis(nama, kode_unit, jenis_transaksi, update_nilai_lama).
Function set_option(name, value) akan mengupdate record tabel sys_options (atau meng-insert baru jika
belum ada) sesuai kriteria sys_options.optname = name. Function get_option(name) akan mengembalikan
nilai string kosong apabila record dengan kriteria sys_options.optname tidak ada – dan jika ada, akan
mengembalikan sys_options.optvalue yang sesuai.
Sedangkan f ungsi gen_nomor_otomatis(nama, kode_unit, jenis_transaksi, update_nilai_lama) akan
mengambil nomor yang sesuai dengan kriteria dari tabel sys_options menggunakan f ungsi get_option,
membuat nomor yang baru jika belum ada, menambahkannya dengan 1, mengupdate kembali ke tabel
sys_options menggunakan f ungsi set_option, dan mengembalikan nomor baru tersebut ke user yang
memanggilnya.
Agar lebih jelas, berikut kode untuk masing-masing f ungsi di atas.
Fungsi get_option()
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017

CREATE DEFINER=`root `@`localhost `FUNCTION `get _opt ion`(`opt _name`varchar(50))
RETURNS varchar(250)
LANGUAGE SQL
NOT DETERMINISTIC
READS SQL DATA
SQL SECURITY INVOKER
COMMENT'Read opt ions'
BEGIN
declare xint eger;
set x = (select count (*)as jmlfrom sys_opt ions owhere o.opt name = opt _name);
if x = 0t hen
ret urn '';
else
ret urn (select opt valuefrom sys_opt ions owhere o.opt name = opt _name);
end if;
END
Fungsi set_option()

0001
0002
0003

CREATE DEFINER=`root `@`localhost `FUNCTION `set _opt ion`(`opt _name`varchar
(50), `opt _value`varchar(255))
RETURNS char(1)
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027

LANGUAGE SQL
NOT DETERMINISTIC
READS SQL DATA
SQL SECURITY INVOKER
COMMENT'Save opt ions'
BEGIN
declare j,xint eger;
declare reschar;
set res='N';
ifcoalesce(opt _name,'') ='' t hen
set res ='N';
else
set x = (select count (*)as jmlfrom sys_opt ions owhere o.opt name = opt _name);
if x = 0t hen
insert int o sys_opt ions (opt name, opt value)values ( opt _name, opt _value);
else
updat e sys_opt ionsset opt value = opt _valuewhere opt name = opt _name;
end if;
set res ='Y';
end if;
ret urn res;
END

Dan berikut ini f ungsi utamanya:
Fungsi gen_nomor_otomatis()
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034

CREATE DEFINER=`acc_x`@`localhost `FUNCTION `gen_nomor_ot omat is`(`nama_kode`
VARCHAR(30), `kode_unit `varCHAR(3), `prefix_t ransaksi`CHAR(3), `updat e_old`cHAR(1))
RETURNS varchar(23)
LANGUAGE SQL
NOT DETERMINISTIC
READS SQL DATA
SQL SECURITY INVOKER
COMMENT''
BEGIN
declare kode_lama, kode_baruvarchar(24);
declare pft varchar(4);
declare iINTEGER;
declare dummychar(3);
declare d1, m1, y1,
d2, m2, y2 int eger;
declare sekarangDATE;
set sekarang =Dat e(Now());
set d1 =day(sekarang);
set m1 =mont h(sekarang);
set y1 =year(sekarang);
#default dat a prefix: TR- (mean t ransact ions)
set pft = if(t rim(prefix_t ransaksi) ='','TRX-', concat (rpad(t rim(prefix_t ransaksi),3,'0'),'-'));
set kode_lama = get _opt ion(concat (nama_kode, pft , kode_unit ));
if lengt h(kode_lama) <>20t hen
set kode_lama = concat (kode_unit ,
pft ,
cast (y1as char),
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069

lpad(cast (m1as char),2,'0'),
lpad(cast (d1as char),2,'0'),
'-00001');
end if;
#generat ed:
set
set
set
set

y2 =cast (subst r(kode_lama, 7,4)as unsigned);
m2 =cast (subst r(kode_lama, 11,2)as unsigned);
d2 =cast (subst r(kode_lama, 13,2)as unsigned);
i =cast (subst r(kode_lama, 16,5)as unsigned);

ifdat e(concat (y2,'-',lpad(cast (m2as char),2,'0'),'-',lpad(cast (d2as char),2,'0'))) >= sekarang
t hen
set i = i +1;
else
set i = 1;
end if;
set y2 = y1;
set m2 = m1;
set d2 = d1;
set kode_lama = concat (
subst r(kode_lama,1,6),
cast (y2as char),
lpad(cast (m2as char),2,'0'),
lpad(cast (d2as char),2,'0'),
'-',
LPAD(cast (ias char),5,'0')
);
ifupper(updat e_old) ='Y' t hen
set dummy = set _opt ion(concat (nama_kode, pft , kode_unit ), kode_lama);
end if;
ret urn kode_lama;
END

Menguji Fungsi-Fungsi Di Atas
Setelah semua stored f unction dibuat, kita akan mencoba menggenerate nomor-nomor transaksi secara
otomatis menggunakan f ungsi gen_nomor_otomatis()…
Di HeidiSQL, masuklah ke tab Query dan ketikkan sebuah query SQL seperti berikut:
0001
0002
0003
0004
0005
0006
0007
0008

/*
Cont oh menggenerat e nomor unt uk
* Jurnal kas masuk
* unit kerja dengan kode"101"
* Jenis t ransaksi KM* Nomor t idak akan diupdat e ke t abel sys_opt ions
*/
select gen_nomor_ot omat is('JURNAL_KAS_Masuk','101','KM-','N');

Lalu jalankan (F9). Anda akan mendapatkan hasil seperti ini:
Jalankanlah SQL di atas berulang-ulang dan Anda akan tetap mendapatkan hasil yang sama. Trus nama
nomor urut otomatisnya? Kalau nomornya itu-itu terus kan sama saja bohong??
Sabar….
Sekarang gantilah SQL di atas menjadi:
0001
0002
0003
0004
0005
0006
0007
0008

/*
Cont oh menggenerat e nomor unt uk
* Jurnal kas masuk
* unit kerja dengan kode"101"
* Jenis t ransaksi KM* Nomor akan diupdat e ke t abel sys_opt ions
*/
select gen_nomor_ot omat is('JURNAL_KAS_Masuk','101','KM-','Y');

Dan lihat hasilnya:

Sudah bertambah bukan?
Kemudian ubahlah SQL untuk menggenerate nomor Purchase Order (PO):
0001
0002
0003
0004
0005
0006
0007

/*
Cont oh menggenerat e nomor unt uk
* PurchaseOrder (PO)
* unit kerja dengan kode"101"
* Jenis t ransaksi PO* Nomor akan diupdat e ke t abel sys_opt ions
*/
0008

*/
select gen_nomor_ot omat is('JURNAL_KAS_Masuk','101','PO-','Y');

Hasilnya:

Bila Anda perhatikan tabel sys_options, tabel tersebut sekarang telah berisi:

Tabel ini akan diupdate setiap permintaan generate nomor otomatis dilakukan. Dan bila ada nomor dengan
kriteria yang baru (misalnya kode unit kerja atau jenis transaksi berbeda), otomatis record baru akan dibuat
untuk menampung nomornya.

Menguji Dengan Aplikasi Di Delphi
Pengujian via SQL di HeidiSQL selesai, tentunya kita ingin mengujinya secara real pada sebuah aplikasi di
Delphi. Saya akan menggunakan Z eos sebagai koneksi dalam pengujian ini, menggunakan Delphi 7…
Meskipun saya menggunakan Z eos dan Delphi 7, tentu saja Anda dapat menggunakan versi Delphi yang lain
dan library koneksi yang berbeda seperti MyDAC atau DBExpress.
Langsung saja.
Buat sebuah projek baru dan tambahkan sebuah koneksi (saya menggunakan T Z Connection) ke f orm. Atur
property-nya dan pastikan sudah terkoneksi ke database kita, yaitu database tes_penomoran_otomatis.
Tambahkan sebuah T Z Query ke f orm dan set property Connection ke Z Connection1.
Tambahkan dua buah T Label, dua buah T Edit dan dua buah T Button ke f orm. Lihat gambar berikut:
Kita akan mengaktif kan koneksi database saat f orm dibuat dengan memanf aatkan event FormCreate:
0001
0002
0003
0004
0005

procedure TForm1.FormCreat e(Sender: TObject );
begin
if not ZConnect ion1.Connect edt hen
ZConnect ion1.Connect ;
end;

Kemudian kita isi event OnClick pada Button1 untuk menggenerate nomor pembelian otomatis dan
menampilkannya ke Edit1:
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022

procedure TForm1.But t on1Click(Sender: TObject );
var
JenisTrans,
KodeUnit ,
NamaKode,
SQL:St ring;
begin
JenisTrans :='TB-';
KodeUnit :='A01';
NamaKode :='Transaksi-Pembelian';
SQL
:='select gen_nomor_ot omat is('+
Quot edSt r(NamaKode)+','+
Quot edSt r(KodeUnit )+','+
Quot edSt r(JenisTrans)+','+
Quot edSt r('Y')+')';
if ZQuery1.Act ivet hen
ZQuery1.Close;
ZQuery1.SQL.Text := SQL;
ZQuery1.Open;
Edit 1.Text := ZQuery1.Fields[0].AsSt ring;
ZQuery1.Close;
end;

Sedangkan untuk Button2 kita gunakan untuk menggenerate nomor penjualan otomatis dan hasilnya kita
tampilkan ke Edit2:
0001
0002
0003
0004
0005
0006
0007

procedure TForm1.But t on2Click(Sender: TObject );
var
JenisTrans,
KodeUnit ,
NamaKode,
SQL:St ring;
begin
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022

JenisTrans :='TJ-';
KodeUnit :='A01';
NamaKode :='Transaksi-Penjualan';
SQL
:='select gen_nomor_ot omat is('+
Quot edSt r(NamaKode)+','+
Quot edSt r(KodeUnit )+','+
Quot edSt r(JenisTrans)+','+
Quot edSt r('Y')+')';
if ZQuery1.Act ivet hen
ZQuery1.Close;
ZQuery1.SQL.Text := SQL;
ZQuery1.Open;
Edit 2.Text := ZQuery1.Fields[0].AsSt ring;
ZQuery1.Close;
end;

Anda boleh menjalankan projek untuk melihat hasilnya. Selanjutnya bila kita perhatikan, ternyata semua
transaksi dapat menggunakan f ormat penomoran yang sama, karenanya semua transaksi dapat
menggunakan stored f unction yang sama yaitu f ungsi gen_nomor_otomatis(). Dari situ kita membuat
sebuah wrapper (pembungkus) berupa sebuah f ungsi di Delphi yang dapat dipanggil oleh semua transaksi –
tentunya dibedakan oleh parameter-parameter sesuai transaksi yang memanggilnya.
Berikut f ungsi wrapper yang akan kita buat, kita deklarasikan sebagai method public pada f orm:
0001
0002
0003
0004
0005
0006
0007
0008

privat e
public
funct ion Generat eNomorOt omat is(JenisTrans, KodeUnit , NamaKode:St ring; Updat e:Boolean
):St ring;
end;

Kemudian klik Ctrl+Shif t+C (Code Completion) untuk membuat implementasi dari f ungsi tersebut:
Jangan lupa di-share

0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022

implement at ion
{$R *.dfm}
funct ion TForm1.Generat eNomorOt omat is(
JenisTrans,
KodeUnit ,
NamaKode:St ring;
Updat e:Boolean):St ring;
var
SQL:St ring;
_updat e:st ring;
begin
result :='Paramet er t idak valid!';
if lengt h(JenisTrans) <>3 t hen exit ;
if lengt h(KodeUnit ) <>3 t hen exit ;
if lengt h(NamaKode) >40 t hen exit ;
if Updat et hen _updat e :='Y' else _updat e :='N';
SQL

:='select gen_nomor_ot omat is('+
Quot edSt r(NamaKode)+','+
Quot edSt r(KodeUnit )+','+
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037

Quot edSt r(JenisTrans)+','+
Quot edSt r(_updat e)+')';
if ZQuery1.Act ivet hen
ZQuery1.Close;
ZQuery1.SQL.Text := SQL;
t ry
ZQuery1.Open;
result := ZQuery1.Fields[0].AsSt ring;
ZQuery1.Close;
except
Result :='Error';
end;
end;

Di situ terlihat bahwa bila parameter tidak sesuai, f ungsi akan mengembalikan string ‘Parameter tidak valid!’.
Demikian pula bila proses query ke database gagal, f ungsi akan mengembalikan nilai ‘Error’.
Dengan adanya wrapper di atas kita tidak perlu lagi repot membuat kode yang panjang setiap akan menggenerate penomoran otomatis di Delphi. Cukup dengan sebaris kode saja. Kita ubah isi event OnClick pada
Button1 dan Button2 untuk menggunakan wrapper di atas, masing-masing sebagai berikut:
0001
0002
0003
0004
0005
0006
0007
0008
0009

procedure TForm1.But t on1Click(Sender: TObject );
begin
Edit 1.Text := Generat eNomorOt omat is('TJ-','A01','Transaksi-Pembelian',True);
end;
procedure TForm1.But t on2Click(Sender: TObject );
begin
Edit 2.Text := Generat eNomorOt omat is('TB-','A01','Transaksi-Penjualan',True);
end;

Sehingga kode selengkapnya menjadi:
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026

unit Unit 1;
int erface
uses
Windows, Messages, SysUt ils, Variant s, Classes, Graphics, Cont rols, Forms,
Dialogs, St dCt rls, ZConnect ion, DB, ZAbst ract RODat aset , ZAbst ract Dat aset ,
ZDat aset ;
t ype
TForm1 =class(TForm)
ZConnect ion1: TZConnect ion;
Edit 1: TEdit ;
Label1: TLabel;
But t on1: TBut t on;
Edit 2: TEdit ;
Label2: TLabel;
But t on2: TBut t on;
ZQuery1: TZQuery;
procedure But t on1Click(Sender: TObject );
procedure But t on2Click(Sender: TObject );
procedure FormCreat e(Sender: TObject );
privat e
public
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085

funct ion Generat eNomorOt omat is(JenisTrans, KodeUnit , NamaKode:St ring; Updat e:
Boolean):St ring;
end;
var
Form1: TForm1;
implement at ion
{$R *.dfm}
funct ion TForm1.Generat eNomorOt omat is(
JenisTrans,
KodeUnit ,
NamaKode:St ring;
Updat e:Boolean):St ring;
var
SQL:St ring;
_updat e:st ring;
begin
result :='Paramet er t idak valid!';
if lengt h(JenisTrans) <>3 t hen exit ;
if lengt h(KodeUnit ) <>3 t hen exit ;
if lengt h(NamaKode) >40 t hen exit ;
if Updat et hen _updat e :='Y' else _updat e :='N';
SQL

:='select gen_nomor_ot omat is('+
Quot edSt r(NamaKode)+','+
Quot edSt r(KodeUnit )+','+
Quot edSt r(JenisTrans)+','+
Quot edSt r(_updat e)+')';
if ZQuery1.Act ivet hen
ZQuery1.Close;
ZQuery1.SQL.Text := SQL;
t ry
ZQuery1.Open;
result := ZQuery1.Fields[0].AsSt ring;
ZQuery1.Close;
except
Result :='Error';
end;
end;
procedure TForm1.But t on1Click(Sender: TObject );
begin
Edit 1.Text := Generat eNomorOt omat is('TJ-','A01','Transaksi-Pembelian',True);
end;
procedure TForm1.But t on2Click(Sender: TObject );
begin
Edit 2.Text := Generat eNomorOt omat is('TB-','A01','Transaksi-Penjualan',True);
end;
procedure TForm1.FormCreat e(Sender: TObject );
begin
if not ZConnect ion1.Connect edt hen
ZConnect ion1.Connect ;
end;
end.

Sekarang silahkan menjalankan projek lagi. Kemudian klik-lah berulang-ulang pada masing-masing button
untuk menggenerate nomor otomatis.
Kemudian tutuplah aplikasi tersebut. Ubah tanggal komputer menjadi esok hari.
Lalu jalankan lagi projeknya. Terlihat bahwa dengan
bergantinya hari, nomor urut otomatis direset dan
dimulai kembali dari nomor urut 1:

Sampai di sini, pembuatan nomor transaksi otomatis dengan Delphi dan MySQL sudah selesai. Tentu Anda
dapat langsung menggunakannya atau mengembangkan sesuai kebutuhan atau dijadikan ref erensi bagi
rekan Delphier lain yang lagi perlu.
Error Gaaan!
Beberapa rakan Delphier melaporkan bahwa kode SQL untuk membuat stored f unction di atas ternyata error
pada Line 9 (ketahuan kalau copas )
Mengcopy mentah-mentah perintah SQL untuk membuat stored f unction di atas, masukkannya ke
editor SQL dan mengeksekusinya bisa dipastikan akan menyebabkan error seperti ini:

Error di atas terjadi karena perintah dianggap berhenti pada baris sembilan, yaitu
Fungsi set_option()
0001
0002
0003

declare xint eger;

Kenapa berhenti di situ, karena di situ ada SQL delimiter, yaitu tanda semikolon (;) yang berarti akhir dari
sebuah perintah SQL. Error di atas dapat diatasi dengan mengikuti panduan umum pembuatan stored
procedure/stored f unction di MySQL: dengan mengganti SQL delimiter ke huruf /tanda lain dulu untuk
sementara.
Untuk contoh, kita akan mengganti delimiter dengan tanda “$$”:
Fungsi set_option()
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024

delimit er $$
CREATE DEFINER=`root `@`localhost `FUNCTION `get _opt ion`(`opt _name`varchar(50))
RETURNS varchar(250)
LANGUAGE SQL
NOT DETERMINISTIC
READS SQL DATA
SQL SECURITY INVOKER
COMMENT'Read opt ions'
BEGIN
declare xint eger;
set x = (select count (*)as jmlfrom sys_opt ions owhere o.opt name = opt _name);
if x = 0t hen
ret urn '';
else
ret urn (select opt valuefrom sys_opt ions owhere o.opt name = opt _name);
end if;
END
$$
delimit er ;

Lalu coba jalankan lagi. Di laptop saya berhasil. Di Laptop Anda?
Oke Sudah Berhasil. Sundul Gaaan!
Trus link downloadnya mana?
Jah elah, manja amat! Begitu aja pake download. Koding sendiri lah biar jemarinya lentik…
# jangan copas kalau berani :p
Salam Delphier,
Joko Rivai

More Related Content

What's hot

Bab ii keg pembel 6 array
Bab ii keg pembel 6  arrayBab ii keg pembel 6  array
Bab ii keg pembel 6 array
087dwi
 
Laporan praktikum modul vii
Laporan praktikum modul viiLaporan praktikum modul vii
Laporan praktikum modul vii
Devi Apriansyah
 
Ix struktur pointer
Ix struktur pointerIx struktur pointer
Ix struktur pointer
Dhan junkie
 
Kamus pl sql
Kamus pl sqlKamus pl sql
Kamus pl sql
Teddy Soleh Susandi
 
Bab 2 identifier dan tipe data
Bab 2 identifier dan tipe dataBab 2 identifier dan tipe data
Bab 2 identifier dan tipe data
Affandi Arrizandy
 
Lapopran praktikum struktur data pertemuan 2 Sorting
Lapopran praktikum struktur data pertemuan 2 SortingLapopran praktikum struktur data pertemuan 2 Sorting
Lapopran praktikum struktur data pertemuan 2 Sorting
Ady Achirul
 
Lapopran praktikum struktur data pertemuan 3 Merge_Sort
Lapopran praktikum struktur data pertemuan 3 Merge_SortLapopran praktikum struktur data pertemuan 3 Merge_Sort
Lapopran praktikum struktur data pertemuan 3 Merge_Sort
Ady Achirul
 
Membuat Sistem Operasi dengan Fasilitas Keyboard
Membuat Sistem Operasi dengan Fasilitas KeyboardMembuat Sistem Operasi dengan Fasilitas Keyboard
Membuat Sistem Operasi dengan Fasilitas Keyboard
Cynthia Caroline
 
3 adp struktur keputusan
3   adp struktur keputusan3   adp struktur keputusan
3 adp struktur keputusan
Chabil_Juniar
 
Aray dan recrd
Aray dan recrdAray dan recrd
Aray dan recrd
555560
 

What's hot (15)

Bab. 7
Bab. 7Bab. 7
Bab. 7
 
Bab ii keg pembel 6 array
Bab ii keg pembel 6  arrayBab ii keg pembel 6  array
Bab ii keg pembel 6 array
 
Laporan praktikum modul vii
Laporan praktikum modul viiLaporan praktikum modul vii
Laporan praktikum modul vii
 
Ix struktur pointer
Ix struktur pointerIx struktur pointer
Ix struktur pointer
 
Kamus pl sql
Kamus pl sqlKamus pl sql
Kamus pl sql
 
Pratikum sistem basis data 3
Pratikum sistem basis data 3Pratikum sistem basis data 3
Pratikum sistem basis data 3
 
Bab 2 identifier dan tipe data
Bab 2 identifier dan tipe dataBab 2 identifier dan tipe data
Bab 2 identifier dan tipe data
 
Lapopran praktikum struktur data pertemuan 2 Sorting
Lapopran praktikum struktur data pertemuan 2 SortingLapopran praktikum struktur data pertemuan 2 Sorting
Lapopran praktikum struktur data pertemuan 2 Sorting
 
Lapopran praktikum struktur data pertemuan 3 Merge_Sort
Lapopran praktikum struktur data pertemuan 3 Merge_SortLapopran praktikum struktur data pertemuan 3 Merge_Sort
Lapopran praktikum struktur data pertemuan 3 Merge_Sort
 
Membuat Sistem Operasi dengan Fasilitas Keyboard
Membuat Sistem Operasi dengan Fasilitas KeyboardMembuat Sistem Operasi dengan Fasilitas Keyboard
Membuat Sistem Operasi dengan Fasilitas Keyboard
 
Arrays c++
Arrays c++Arrays c++
Arrays c++
 
Function c++
Function c++Function c++
Function c++
 
Modul mysql5
Modul mysql5Modul mysql5
Modul mysql5
 
3 adp struktur keputusan
3   adp struktur keputusan3   adp struktur keputusan
3 adp struktur keputusan
 
Aray dan recrd
Aray dan recrdAray dan recrd
Aray dan recrd
 

Similar to Cenadep.org - Tutorial Penomoran Transaksi Otomatis Dengan Delphi Dan MySQL

2. Array of Record (Struktur Data)
2. Array of Record (Struktur Data)2. Array of Record (Struktur Data)
2. Array of Record (Struktur Data)
Kelinci Coklat
 
Tugas mu'thi modul pascal
Tugas mu'thi modul pascalTugas mu'thi modul pascal
Tugas mu'thi modul pascal
Mu'thi Cinsayf
 
pertemuan ke-4 (Variabel dan Konstanta).ppt
pertemuan ke-4 (Variabel dan Konstanta).pptpertemuan ke-4 (Variabel dan Konstanta).ppt
pertemuan ke-4 (Variabel dan Konstanta).ppt
nafilarifki1
 
Dasar Pemrograman materi kuliah
Dasar Pemrograman materi kuliahDasar Pemrograman materi kuliah
Dasar Pemrograman materi kuliah
Braga Rezpect
 
Laporan praktikum modul viii
Laporan praktikum modul viiiLaporan praktikum modul viii
Laporan praktikum modul viii
Devi Apriansyah
 
Part 13: Penggunaan Tipe Data Real
Part 13: Penggunaan Tipe Data RealPart 13: Penggunaan Tipe Data Real
Part 13: Penggunaan Tipe Data Real
Syaiful Ahdan
 
Pengenalan pascal asli
Pengenalan pascal asliPengenalan pascal asli
Pengenalan pascal asliNadya Olivia
 
mengenal fungsi-fungsi diSQL Server
mengenal fungsi-fungsi diSQL Servermengenal fungsi-fungsi diSQL Server
mengenal fungsi-fungsi diSQL Server
syahrul ramadan
 
Pendahuluan, pembahasan, penutup dan daftar pustaka Makalah Algoritma dan Pem...
Pendahuluan, pembahasan, penutup dan daftar pustaka Makalah Algoritma dan Pem...Pendahuluan, pembahasan, penutup dan daftar pustaka Makalah Algoritma dan Pem...
Pendahuluan, pembahasan, penutup dan daftar pustaka Makalah Algoritma dan Pem...
Rizka Putri Silvyaningrum
 
Assembly ok3
Assembly ok3Assembly ok3
Assembly ok3
Dhan junkie
 
Pelatihan Python Standard Library
Pelatihan Python Standard LibraryPelatihan Python Standard Library
Pelatihan Python Standard LibraryRidwan Fadjar
 
Matlab 3
Matlab 3Matlab 3
Matlab 3
Hastih Leo
 
Fungsi
FungsiFungsi
Fungsi
Rahmat Rijal
 
Sistem bilangan4
Sistem bilangan4Sistem bilangan4
Sistem bilangan4
adealfarisi
 
Tugas1
Tugas1Tugas1
Tugas1
Av Ri
 
5. pemrograman array dan_string
5. pemrograman array dan_string5. pemrograman array dan_string
5. pemrograman array dan_stringRoziq Bahtiar
 
ppt BAB 1.pptx
ppt BAB 1.pptxppt BAB 1.pptx
ppt BAB 1.pptx
desterinahana
 

Similar to Cenadep.org - Tutorial Penomoran Transaksi Otomatis Dengan Delphi Dan MySQL (20)

Tipe data
Tipe dataTipe data
Tipe data
 
2. Array of Record (Struktur Data)
2. Array of Record (Struktur Data)2. Array of Record (Struktur Data)
2. Array of Record (Struktur Data)
 
Bab. 8
Bab. 8Bab. 8
Bab. 8
 
Tugas mu'thi modul pascal
Tugas mu'thi modul pascalTugas mu'thi modul pascal
Tugas mu'thi modul pascal
 
pertemuan ke-4 (Variabel dan Konstanta).ppt
pertemuan ke-4 (Variabel dan Konstanta).pptpertemuan ke-4 (Variabel dan Konstanta).ppt
pertemuan ke-4 (Variabel dan Konstanta).ppt
 
Cc++
Cc++Cc++
Cc++
 
Dasar Pemrograman materi kuliah
Dasar Pemrograman materi kuliahDasar Pemrograman materi kuliah
Dasar Pemrograman materi kuliah
 
Laporan praktikum modul viii
Laporan praktikum modul viiiLaporan praktikum modul viii
Laporan praktikum modul viii
 
Part 13: Penggunaan Tipe Data Real
Part 13: Penggunaan Tipe Data RealPart 13: Penggunaan Tipe Data Real
Part 13: Penggunaan Tipe Data Real
 
Pengenalan pascal asli
Pengenalan pascal asliPengenalan pascal asli
Pengenalan pascal asli
 
mengenal fungsi-fungsi diSQL Server
mengenal fungsi-fungsi diSQL Servermengenal fungsi-fungsi diSQL Server
mengenal fungsi-fungsi diSQL Server
 
Pendahuluan, pembahasan, penutup dan daftar pustaka Makalah Algoritma dan Pem...
Pendahuluan, pembahasan, penutup dan daftar pustaka Makalah Algoritma dan Pem...Pendahuluan, pembahasan, penutup dan daftar pustaka Makalah Algoritma dan Pem...
Pendahuluan, pembahasan, penutup dan daftar pustaka Makalah Algoritma dan Pem...
 
Assembly ok3
Assembly ok3Assembly ok3
Assembly ok3
 
Pelatihan Python Standard Library
Pelatihan Python Standard LibraryPelatihan Python Standard Library
Pelatihan Python Standard Library
 
Matlab 3
Matlab 3Matlab 3
Matlab 3
 
Fungsi
FungsiFungsi
Fungsi
 
Sistem bilangan4
Sistem bilangan4Sistem bilangan4
Sistem bilangan4
 
Tugas1
Tugas1Tugas1
Tugas1
 
5. pemrograman array dan_string
5. pemrograman array dan_string5. pemrograman array dan_string
5. pemrograman array dan_string
 
ppt BAB 1.pptx
ppt BAB 1.pptxppt BAB 1.pptx
ppt BAB 1.pptx
 

Cenadep.org - Tutorial Penomoran Transaksi Otomatis Dengan Delphi Dan MySQL

  • 1. ce nade p.o rg http://www.cenadep.o rg/2013/11/18/peno mo ran-transaksi-o to matis-dengan-delphi-mysql/ Penomoran Transaksi Otomatis Dengan Delphi & MySQL Dalam tulisan kali ini kita akan membuat sebuah contoh penomoran otomatis dengan database MySQL untuk berbagai macam transaksi dalam aplikasi. Sebelum melanjutkan, kita lihat dulu seperti apa penomoran yang akan kita buat. Penomoran dalam contoh ini memiliki kriteria sebagai berikut: Menyertakan kode unit, yaitu kode unit kerja yang bertransaksi. Ini bermanf aat untuk aplikasi yang memiliki f itur multi-unit atau cabang perusahaan. Menyertakan kode transaksi, untuk memudahkan pengenalan nomor transaksi. Misalnya JU untuk Jurnal Umum, KM untuk Kas Masuk, PO untuk Purchase Order, RB untuk Retur Pembelian, SO untuk Stock Opname, dsb. Menyertakan tanggal transaksi Menyertakan nomor urut per tanggal transaksi, direset ke 1 apabila tanggak berganti. Dari kriteria di atas, ini contoh nomor transaksinya: 101PO-20131118-00006 Di mana: 101 adalah kode unit kerja. Saya anggap bahwa kode unit kerja adalah 001 sampai 999 (varchar [3]). PO- adalah pref ix transaksi (jenis transaksi). Dalam hal ini, PO- berarti Purchase Order (Pembelian). 20131118 adalah tanggal transaksi 00006 adalah nomor urut transaksi harian. Dalam contoh, nomor di atas adalah nomor transaksi Purchase Order yang keenam dalam tanggal 18 November 2013. Panjang nomor di atas adalah 20 karakter. Angka 20 ini harus baku, tidak boleh diubah, agar tidak merusak f ormat/pemotongan kode-kode dalam nomor sesuai kriteria. Bila Anda ingin membuat nomor sendiri yang panjangnya dinamis, cara dalam tulisan ini tidak dapat dipakai begitu saja melainkan memerlukan modif ikasi. Dalam tulisan ini kita anggap bahwa panjang kode unit cukup 3 karakter, panjang pref ix transaksi (jenis transaksi) 3 karakter: dalam contoh, terdiri dari dua huruf jenis transaksi dan satu huruf pemisah “-”. Sedangkan panjang nomor urut adalah 5 karakter dan memuat sampai 99.999 transaksi per hari untuk tiap jenis transaksi. Penomoran ini akan disimpan dan diupdate ke database sehingga dapat dipakai oleh multi-client. Anggap ada dua klien yang terhubung ke server, yang satu mendapatkan nomor urut 101PO-20131118-00006 sedangkan klien lainnya mendapatkan nomor urut 101PO-20131118-00007 secara otomatis sehingga menjamin keunikan nomor transaksi. Bila nomor ini disimpan di klien, bisa terjadi tabrakan apabila ada nomor yang sama dari klien yang berbeda. Selanjutnya bila nomor tetap disimpan di database tapi digenerate di aplikasi (klien) tentu akan memperlambat sistem, karena ada pertukaran data yang tidak perlu antara sever dan klien. Persiapan Database Dan Tabel Kembali saya ingatkan, nomor dan kriterianya akan disimpan dalam database. Karenanya kita perlu sebuah database dan sebuah tabel untuk menampung nomor-nomor transaksi yang digenerate.
  • 2. Pertama, kita buat sebuah database baru di MySQL. Untuk mempermudah interaksi dengan MySQL server, saya sarankan untuk menggunakan HeidiSQL, antarmuka GUI gratis untuk MySQL. Loginlah ke MySQL dan buat sebuah database baru dengan nama tes_penomoran_otomatis. Selanjutnya buatlah sebuah tabel dengan nama sys_options yang berisi dua f ield: optname dan optvalue. Tabel ini akan digunakan untuk menampung variabel dan nilainya. Dalam contoh penomoran otomatis dengan Delphi dan MySQL ini, kita akan menampung variabel [nama_nomor] dan [nilai_nomor_terakhir]. Setiap saat kita perlu menggenerate nomor baru, tabel ini akan diupdate: record dengan [nama_nomor] yang sesuai akan diambil nilainya, diupdate (bertambah 1), disave kembali ke database dan nilai hasil update akan dikembalikan ke user. Bila [nama_nomor] ini masih kosong (f ield [nilai_nomor_terakhir] masih kosong), akan dibuat yang baru berisi nilai nomor pertama dengan nomor urut 00001. Secara pseudo (gambaran), proses generate dan update nomor otomatis ini dapat dilihat pada diagram berikut: Kembali ke tabel sys_options tadi, silahkan gunakan kode berikut untuk membuatnya: 0001 0002 0003 0004 0005 CREATE TABLE `sys_opt ions` ( `opt name`VARCHAR(50)NOT NULL, `opt value` TINYTEXTNULL, PRIMARY KEY (`opt name`) ); Selain bermanf aat untuk menampung nomor otomatis, tabel ini juga dapat digunakan untuk menampung data lainnya, misalnya user yang terakhir login, setting printer/kertas, dsb.
  • 3. Menggunakan Stored Function Karena proses generate dilakukan dalam database dan melibatkan proses update, insert atau delete, kita akan menggunakan stored f unction untuk mempermudah pekerjaan menggenerate dan update nomor pada tabel sys_options… Kita membutuhkan 3 buah stored f unction dalam hal ini: set_option(name, value), get_option(name), gen_nomor_otomatis(nama, kode_unit, jenis_transaksi, update_nilai_lama). Function set_option(name, value) akan mengupdate record tabel sys_options (atau meng-insert baru jika belum ada) sesuai kriteria sys_options.optname = name. Function get_option(name) akan mengembalikan nilai string kosong apabila record dengan kriteria sys_options.optname tidak ada – dan jika ada, akan mengembalikan sys_options.optvalue yang sesuai. Sedangkan f ungsi gen_nomor_otomatis(nama, kode_unit, jenis_transaksi, update_nilai_lama) akan mengambil nomor yang sesuai dengan kriteria dari tabel sys_options menggunakan f ungsi get_option, membuat nomor yang baru jika belum ada, menambahkannya dengan 1, mengupdate kembali ke tabel sys_options menggunakan f ungsi set_option, dan mengembalikan nomor baru tersebut ke user yang memanggilnya. Agar lebih jelas, berikut kode untuk masing-masing f ungsi di atas. Fungsi get_option() 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 CREATE DEFINER=`root `@`localhost `FUNCTION `get _opt ion`(`opt _name`varchar(50)) RETURNS varchar(250) LANGUAGE SQL NOT DETERMINISTIC READS SQL DATA SQL SECURITY INVOKER COMMENT'Read opt ions' BEGIN declare xint eger; set x = (select count (*)as jmlfrom sys_opt ions owhere o.opt name = opt _name); if x = 0t hen ret urn ''; else ret urn (select opt valuefrom sys_opt ions owhere o.opt name = opt _name); end if; END Fungsi set_option() 0001 0002 0003 CREATE DEFINER=`root `@`localhost `FUNCTION `set _opt ion`(`opt _name`varchar (50), `opt _value`varchar(255)) RETURNS char(1)
  • 4. 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 LANGUAGE SQL NOT DETERMINISTIC READS SQL DATA SQL SECURITY INVOKER COMMENT'Save opt ions' BEGIN declare j,xint eger; declare reschar; set res='N'; ifcoalesce(opt _name,'') ='' t hen set res ='N'; else set x = (select count (*)as jmlfrom sys_opt ions owhere o.opt name = opt _name); if x = 0t hen insert int o sys_opt ions (opt name, opt value)values ( opt _name, opt _value); else updat e sys_opt ionsset opt value = opt _valuewhere opt name = opt _name; end if; set res ='Y'; end if; ret urn res; END Dan berikut ini f ungsi utamanya: Fungsi gen_nomor_otomatis() 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 CREATE DEFINER=`acc_x`@`localhost `FUNCTION `gen_nomor_ot omat is`(`nama_kode` VARCHAR(30), `kode_unit `varCHAR(3), `prefix_t ransaksi`CHAR(3), `updat e_old`cHAR(1)) RETURNS varchar(23) LANGUAGE SQL NOT DETERMINISTIC READS SQL DATA SQL SECURITY INVOKER COMMENT'' BEGIN declare kode_lama, kode_baruvarchar(24); declare pft varchar(4); declare iINTEGER; declare dummychar(3); declare d1, m1, y1, d2, m2, y2 int eger; declare sekarangDATE; set sekarang =Dat e(Now()); set d1 =day(sekarang); set m1 =mont h(sekarang); set y1 =year(sekarang); #default dat a prefix: TR- (mean t ransact ions) set pft = if(t rim(prefix_t ransaksi) ='','TRX-', concat (rpad(t rim(prefix_t ransaksi),3,'0'),'-')); set kode_lama = get _opt ion(concat (nama_kode, pft , kode_unit )); if lengt h(kode_lama) <>20t hen set kode_lama = concat (kode_unit , pft , cast (y1as char),
  • 5. 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 lpad(cast (m1as char),2,'0'), lpad(cast (d1as char),2,'0'), '-00001'); end if; #generat ed: set set set set y2 =cast (subst r(kode_lama, 7,4)as unsigned); m2 =cast (subst r(kode_lama, 11,2)as unsigned); d2 =cast (subst r(kode_lama, 13,2)as unsigned); i =cast (subst r(kode_lama, 16,5)as unsigned); ifdat e(concat (y2,'-',lpad(cast (m2as char),2,'0'),'-',lpad(cast (d2as char),2,'0'))) >= sekarang t hen set i = i +1; else set i = 1; end if; set y2 = y1; set m2 = m1; set d2 = d1; set kode_lama = concat ( subst r(kode_lama,1,6), cast (y2as char), lpad(cast (m2as char),2,'0'), lpad(cast (d2as char),2,'0'), '-', LPAD(cast (ias char),5,'0') ); ifupper(updat e_old) ='Y' t hen set dummy = set _opt ion(concat (nama_kode, pft , kode_unit ), kode_lama); end if; ret urn kode_lama; END Menguji Fungsi-Fungsi Di Atas Setelah semua stored f unction dibuat, kita akan mencoba menggenerate nomor-nomor transaksi secara otomatis menggunakan f ungsi gen_nomor_otomatis()… Di HeidiSQL, masuklah ke tab Query dan ketikkan sebuah query SQL seperti berikut: 0001 0002 0003 0004 0005 0006 0007 0008 /* Cont oh menggenerat e nomor unt uk * Jurnal kas masuk * unit kerja dengan kode"101" * Jenis t ransaksi KM* Nomor t idak akan diupdat e ke t abel sys_opt ions */ select gen_nomor_ot omat is('JURNAL_KAS_Masuk','101','KM-','N'); Lalu jalankan (F9). Anda akan mendapatkan hasil seperti ini:
  • 6. Jalankanlah SQL di atas berulang-ulang dan Anda akan tetap mendapatkan hasil yang sama. Trus nama nomor urut otomatisnya? Kalau nomornya itu-itu terus kan sama saja bohong?? Sabar…. Sekarang gantilah SQL di atas menjadi: 0001 0002 0003 0004 0005 0006 0007 0008 /* Cont oh menggenerat e nomor unt uk * Jurnal kas masuk * unit kerja dengan kode"101" * Jenis t ransaksi KM* Nomor akan diupdat e ke t abel sys_opt ions */ select gen_nomor_ot omat is('JURNAL_KAS_Masuk','101','KM-','Y'); Dan lihat hasilnya: Sudah bertambah bukan? Kemudian ubahlah SQL untuk menggenerate nomor Purchase Order (PO): 0001 0002 0003 0004 0005 0006 0007 /* Cont oh menggenerat e nomor unt uk * PurchaseOrder (PO) * unit kerja dengan kode"101" * Jenis t ransaksi PO* Nomor akan diupdat e ke t abel sys_opt ions */
  • 7. 0008 */ select gen_nomor_ot omat is('JURNAL_KAS_Masuk','101','PO-','Y'); Hasilnya: Bila Anda perhatikan tabel sys_options, tabel tersebut sekarang telah berisi: Tabel ini akan diupdate setiap permintaan generate nomor otomatis dilakukan. Dan bila ada nomor dengan kriteria yang baru (misalnya kode unit kerja atau jenis transaksi berbeda), otomatis record baru akan dibuat untuk menampung nomornya. Menguji Dengan Aplikasi Di Delphi Pengujian via SQL di HeidiSQL selesai, tentunya kita ingin mengujinya secara real pada sebuah aplikasi di Delphi. Saya akan menggunakan Z eos sebagai koneksi dalam pengujian ini, menggunakan Delphi 7… Meskipun saya menggunakan Z eos dan Delphi 7, tentu saja Anda dapat menggunakan versi Delphi yang lain dan library koneksi yang berbeda seperti MyDAC atau DBExpress. Langsung saja. Buat sebuah projek baru dan tambahkan sebuah koneksi (saya menggunakan T Z Connection) ke f orm. Atur property-nya dan pastikan sudah terkoneksi ke database kita, yaitu database tes_penomoran_otomatis. Tambahkan sebuah T Z Query ke f orm dan set property Connection ke Z Connection1. Tambahkan dua buah T Label, dua buah T Edit dan dua buah T Button ke f orm. Lihat gambar berikut:
  • 8. Kita akan mengaktif kan koneksi database saat f orm dibuat dengan memanf aatkan event FormCreate: 0001 0002 0003 0004 0005 procedure TForm1.FormCreat e(Sender: TObject ); begin if not ZConnect ion1.Connect edt hen ZConnect ion1.Connect ; end; Kemudian kita isi event OnClick pada Button1 untuk menggenerate nomor pembelian otomatis dan menampilkannya ke Edit1: 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 procedure TForm1.But t on1Click(Sender: TObject ); var JenisTrans, KodeUnit , NamaKode, SQL:St ring; begin JenisTrans :='TB-'; KodeUnit :='A01'; NamaKode :='Transaksi-Pembelian'; SQL :='select gen_nomor_ot omat is('+ Quot edSt r(NamaKode)+','+ Quot edSt r(KodeUnit )+','+ Quot edSt r(JenisTrans)+','+ Quot edSt r('Y')+')'; if ZQuery1.Act ivet hen ZQuery1.Close; ZQuery1.SQL.Text := SQL; ZQuery1.Open; Edit 1.Text := ZQuery1.Fields[0].AsSt ring; ZQuery1.Close; end; Sedangkan untuk Button2 kita gunakan untuk menggenerate nomor penjualan otomatis dan hasilnya kita tampilkan ke Edit2: 0001 0002 0003 0004 0005 0006 0007 procedure TForm1.But t on2Click(Sender: TObject ); var JenisTrans, KodeUnit , NamaKode, SQL:St ring; begin
  • 9. 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 JenisTrans :='TJ-'; KodeUnit :='A01'; NamaKode :='Transaksi-Penjualan'; SQL :='select gen_nomor_ot omat is('+ Quot edSt r(NamaKode)+','+ Quot edSt r(KodeUnit )+','+ Quot edSt r(JenisTrans)+','+ Quot edSt r('Y')+')'; if ZQuery1.Act ivet hen ZQuery1.Close; ZQuery1.SQL.Text := SQL; ZQuery1.Open; Edit 2.Text := ZQuery1.Fields[0].AsSt ring; ZQuery1.Close; end; Anda boleh menjalankan projek untuk melihat hasilnya. Selanjutnya bila kita perhatikan, ternyata semua transaksi dapat menggunakan f ormat penomoran yang sama, karenanya semua transaksi dapat menggunakan stored f unction yang sama yaitu f ungsi gen_nomor_otomatis(). Dari situ kita membuat sebuah wrapper (pembungkus) berupa sebuah f ungsi di Delphi yang dapat dipanggil oleh semua transaksi – tentunya dibedakan oleh parameter-parameter sesuai transaksi yang memanggilnya. Berikut f ungsi wrapper yang akan kita buat, kita deklarasikan sebagai method public pada f orm: 0001 0002 0003 0004 0005 0006 0007 0008 privat e public funct ion Generat eNomorOt omat is(JenisTrans, KodeUnit , NamaKode:St ring; Updat e:Boolean ):St ring; end; Kemudian klik Ctrl+Shif t+C (Code Completion) untuk membuat implementasi dari f ungsi tersebut: Jangan lupa di-share 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 implement at ion {$R *.dfm} funct ion TForm1.Generat eNomorOt omat is( JenisTrans, KodeUnit , NamaKode:St ring; Updat e:Boolean):St ring; var SQL:St ring; _updat e:st ring; begin result :='Paramet er t idak valid!'; if lengt h(JenisTrans) <>3 t hen exit ; if lengt h(KodeUnit ) <>3 t hen exit ; if lengt h(NamaKode) >40 t hen exit ; if Updat et hen _updat e :='Y' else _updat e :='N'; SQL :='select gen_nomor_ot omat is('+ Quot edSt r(NamaKode)+','+ Quot edSt r(KodeUnit )+','+
  • 10. 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 Quot edSt r(JenisTrans)+','+ Quot edSt r(_updat e)+')'; if ZQuery1.Act ivet hen ZQuery1.Close; ZQuery1.SQL.Text := SQL; t ry ZQuery1.Open; result := ZQuery1.Fields[0].AsSt ring; ZQuery1.Close; except Result :='Error'; end; end; Di situ terlihat bahwa bila parameter tidak sesuai, f ungsi akan mengembalikan string ‘Parameter tidak valid!’. Demikian pula bila proses query ke database gagal, f ungsi akan mengembalikan nilai ‘Error’. Dengan adanya wrapper di atas kita tidak perlu lagi repot membuat kode yang panjang setiap akan menggenerate penomoran otomatis di Delphi. Cukup dengan sebaris kode saja. Kita ubah isi event OnClick pada Button1 dan Button2 untuk menggunakan wrapper di atas, masing-masing sebagai berikut: 0001 0002 0003 0004 0005 0006 0007 0008 0009 procedure TForm1.But t on1Click(Sender: TObject ); begin Edit 1.Text := Generat eNomorOt omat is('TJ-','A01','Transaksi-Pembelian',True); end; procedure TForm1.But t on2Click(Sender: TObject ); begin Edit 2.Text := Generat eNomorOt omat is('TB-','A01','Transaksi-Penjualan',True); end; Sehingga kode selengkapnya menjadi: 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 unit Unit 1; int erface uses Windows, Messages, SysUt ils, Variant s, Classes, Graphics, Cont rols, Forms, Dialogs, St dCt rls, ZConnect ion, DB, ZAbst ract RODat aset , ZAbst ract Dat aset , ZDat aset ; t ype TForm1 =class(TForm) ZConnect ion1: TZConnect ion; Edit 1: TEdit ; Label1: TLabel; But t on1: TBut t on; Edit 2: TEdit ; Label2: TLabel; But t on2: TBut t on; ZQuery1: TZQuery; procedure But t on1Click(Sender: TObject ); procedure But t on2Click(Sender: TObject ); procedure FormCreat e(Sender: TObject ); privat e public
  • 11. 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 funct ion Generat eNomorOt omat is(JenisTrans, KodeUnit , NamaKode:St ring; Updat e: Boolean):St ring; end; var Form1: TForm1; implement at ion {$R *.dfm} funct ion TForm1.Generat eNomorOt omat is( JenisTrans, KodeUnit , NamaKode:St ring; Updat e:Boolean):St ring; var SQL:St ring; _updat e:st ring; begin result :='Paramet er t idak valid!'; if lengt h(JenisTrans) <>3 t hen exit ; if lengt h(KodeUnit ) <>3 t hen exit ; if lengt h(NamaKode) >40 t hen exit ; if Updat et hen _updat e :='Y' else _updat e :='N'; SQL :='select gen_nomor_ot omat is('+ Quot edSt r(NamaKode)+','+ Quot edSt r(KodeUnit )+','+ Quot edSt r(JenisTrans)+','+ Quot edSt r(_updat e)+')'; if ZQuery1.Act ivet hen ZQuery1.Close; ZQuery1.SQL.Text := SQL; t ry ZQuery1.Open; result := ZQuery1.Fields[0].AsSt ring; ZQuery1.Close; except Result :='Error'; end; end; procedure TForm1.But t on1Click(Sender: TObject ); begin Edit 1.Text := Generat eNomorOt omat is('TJ-','A01','Transaksi-Pembelian',True); end; procedure TForm1.But t on2Click(Sender: TObject ); begin Edit 2.Text := Generat eNomorOt omat is('TB-','A01','Transaksi-Penjualan',True); end; procedure TForm1.FormCreat e(Sender: TObject ); begin if not ZConnect ion1.Connect edt hen ZConnect ion1.Connect ; end; end. Sekarang silahkan menjalankan projek lagi. Kemudian klik-lah berulang-ulang pada masing-masing button untuk menggenerate nomor otomatis.
  • 12. Kemudian tutuplah aplikasi tersebut. Ubah tanggal komputer menjadi esok hari. Lalu jalankan lagi projeknya. Terlihat bahwa dengan bergantinya hari, nomor urut otomatis direset dan dimulai kembali dari nomor urut 1: Sampai di sini, pembuatan nomor transaksi otomatis dengan Delphi dan MySQL sudah selesai. Tentu Anda dapat langsung menggunakannya atau mengembangkan sesuai kebutuhan atau dijadikan ref erensi bagi rekan Delphier lain yang lagi perlu. Error Gaaan! Beberapa rakan Delphier melaporkan bahwa kode SQL untuk membuat stored f unction di atas ternyata error pada Line 9 (ketahuan kalau copas )
  • 13. Mengcopy mentah-mentah perintah SQL untuk membuat stored f unction di atas, masukkannya ke editor SQL dan mengeksekusinya bisa dipastikan akan menyebabkan error seperti ini: Error di atas terjadi karena perintah dianggap berhenti pada baris sembilan, yaitu Fungsi set_option() 0001 0002 0003 declare xint eger; Kenapa berhenti di situ, karena di situ ada SQL delimiter, yaitu tanda semikolon (;) yang berarti akhir dari sebuah perintah SQL. Error di atas dapat diatasi dengan mengikuti panduan umum pembuatan stored procedure/stored f unction di MySQL: dengan mengganti SQL delimiter ke huruf /tanda lain dulu untuk sementara. Untuk contoh, kita akan mengganti delimiter dengan tanda “$$”: Fungsi set_option() 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 delimit er $$ CREATE DEFINER=`root `@`localhost `FUNCTION `get _opt ion`(`opt _name`varchar(50)) RETURNS varchar(250) LANGUAGE SQL NOT DETERMINISTIC READS SQL DATA SQL SECURITY INVOKER COMMENT'Read opt ions' BEGIN declare xint eger; set x = (select count (*)as jmlfrom sys_opt ions owhere o.opt name = opt _name); if x = 0t hen ret urn ''; else ret urn (select opt valuefrom sys_opt ions owhere o.opt name = opt _name); end if; END $$ delimit er ; Lalu coba jalankan lagi. Di laptop saya berhasil. Di Laptop Anda? Oke Sudah Berhasil. Sundul Gaaan!
  • 14. Trus link downloadnya mana? Jah elah, manja amat! Begitu aja pake download. Koding sendiri lah biar jemarinya lentik… # jangan copas kalau berani :p Salam Delphier, Joko Rivai