Dataset to CSV Export
Zaman zaman, çoğumuz veri tabanındaki bir tablodan bazen Excel, bazen de diğer veritabanlarına veri aktarmak zorunda kalabiliyoruz. Genelde kullanıcılar da bu tarz bir istekle bize gelebiliyor. Çoğunlukla kullanıcıların ihtiyacı, verileri Excel gibi programlara aktarıp üzerinde çalışma yapmak oluyor. Kullanıcıların bu tarz isteklerini karşılayacak bir çalışmayı paylaşmak istedim.
Aşağıda kodlarını verdiğim çalışma, bir TDataSet nesnesinden türetilmiş olan tüm DataSet mirasçısı nesnelerde rahatlıkla kullanılabilir. TUNIQuery, TUNITable, TADODataSet, TFDQuery, TCustomSQLDataSet, TSQLQuery, TVirtualTable, TVirtualQuery, TVirtualDataSet, TdxMemData, TCustomClientDataSet, TClientDataSet, TInternalSQLDataSet, TSimpleDataSet ve unuttuğum diğerleri bunlara örnek verilebilir.
Tabi bunu sağlamak için (alışkanlık oldu artık) Class Helper tekniğini kullandım, dolayısıyla (XE2 ve öncesi idi “sanırım”) eski Delphi sürümlerinde (en azından bu haliyle) çalışmayabilir. Şayet öyleyse ExportToCSV prosedürünü açığa alıp , prosedür içindeki Self ifadelerini de (“aDataSet: TDataSet” gibi) bir parametreye bağlayabilirsiniz…
CSV Formatına gelecek olursak, “Comma Separated Values” kelimelerinin baş harfleri kullanılarak isimlendirilmiştir. Bu dosyalar, virgülle ayrılmış değerler içeren bir dosyadır. En üst satırında başlıklar, devamında ise metin ve sayılar içeren tablo şeklinde dökme bir veri listesi yer alır. Hücre ve satır mantığına uygundur. Hücreler virgül, noktalı virgül veya tab karakteriyle, satırlar ise #13#10 karakterleriyle birbirinden ayrılabilir. Bu dosyalar daha çok elektronik tablo verilerini bir programdan diğerine kolayca aktarmak için kullanılır. CSV dosyaları, Excel ile veya lotus 123 gibi diğer elektronik tablo programlarıyla da kullanılabilir. CSV dosyaları sadece ham veri içerdiği, hücreler arasında bir bağ kurulmadığı, grafiksel ve binary öğeleri barındırmayan bir yapısı olması nedeniyle JSON, BSON, XML gibi diğer veri aktarım türlerinden bu anlamda ayrışır.
// =============================================
// Author: Uğur PARLAYAN
// Create Date: 2015-04-15-1530
// Description : Genel Helper Classların toplandığı birimdir...
// =============================================
unit Helpers_Data;
interface
uses
Data.DB // TBookmarks, TDataSet
, System.SysUtils // TFileName, Format, FormatDateTime, QuotedString
;
type
TStringArray = array of string;
TStringArrayHelper = record helper for TStringArray
public
function Ayracli(aAyrac: String): String;
//...
end;
{ DATABASE }
TDataSetHelper = class helper for TDataSet
public
procedure ExportToCSV(aFileName: TFileName; const aEncoding: TEncoding; aAyrac: String = ';');
//...
end;
implementation
uses
System.Variants // NULL fonksiyonu...
, System.Classes // TStreamWriter
;
{ TStringArrayHelper }
function TStringArrayHelper.Ayracli(aAyrac: String): String;
var
I: Integer;
begin
for I := Low(Self) to High(Self)
do if (I < High(Self) )
then Result := Result + Self[I] + aAyrac
else Result := Result + Self[I];
end;
{ TDataSetHelper }
procedure TDataSetHelper.ExportToCSV(aFileName: TFileName; const aEncoding: TEncoding; aAyrac: String = ';');
var
I : Integer; // Klasik genel sayaç değişkenimiz...
Dosya : TStreamWriter; // UTF8 şeklinde BOMLU olarak kodlanacak olan dosyayı temsil eder...
Imlec : TBookmark; // Kullanıcı, Datasetin hangi satırında bilgisini tutar...
Hucre : TStringArray; // Sütunları, Fieldleri temsil eder...
function TQ(aString: String): String;
begin
Result := format('"%s"', [aString.Trim]);
end;
begin
if (Self.Active = FALSE)
or (Self.IsEmpty = TRUE) then Exit;
Imlec := Self.Bookmark; // Datasetin mevcut konumunu imleç değişkenine alıyoruz.
Self.DisableControls; // görsel senkronizasyonu devre dışı bırakıyoruz, böylece işlemler daha hızlı ilerliyor...
Self.First; // En baştaki kayda geçiyoruz.
try
Dosya := TStreamWriter.Create(aFileName, False, aEncoding); // Parametreyi "TEncoding.UTF8" olarak verirseniz dosya UTF8 şeklinde kodlanacak ve "BOMLU" olarak oluşturulacaktır...
try
SetLength(Hucre, Self.Fields.Count); // dinamik bir dizi olduğu için bellekte alan tahsisi yapıyoruz...
for I := 0 to Self.Fields.Count - 1
do Hucre[I] := TQ(Self.Fields[I].FieldName); // alan başlıklarını en tepeye çekiyoruz.
Dosya.WriteLine( Hucre.Ayracli( aAyrac ) ); // Alanlar dizisinin her bir hücrenin "ARASINA" noktalı virgül basıyor ve dosyamıza tek satır halinde "SÜTUN BAŞLIKLARINI" yazıyoruz...
while not Self.Eof do begin // Tüm Dataseti baştan sona tarayacağız...
for I := 0 to Self.Fields.Count - 1 do begin // Tüm sütunları/Alanları tek tek elden geçireceğiz...
if (Self.Fields[I].DataType
in [ ftByte // 8 bit tamsayı
, ftShortint // 8 bit tamsayı
, ftSmallint // 16 bit tamsayı
, ftWord // 16 bir işaretsiz tamsayı
, ftInteger // 32 bit tamsayı
, ftFloat // 32 bit Floating-point sayısalı
, ftAutoInc // 32 bit tamsayı
, ftSingle // 32 bit işaretsiz tamsayı
, ftLongWord // 32 bit işaretsiz tamsayı
, ftCurrency // 80 bit Floating-point sayısalı
, ftBCD // 80 bit // BCD = Binary Coded Decimal
, ftLargeint // 64 bit işaretsiz tamsayı
, ftExtended // 80 bit
//, ftFMTBcd // String gibi işlenir...
])
then Dosya.Write( Self.Fields[I].AsString ) // Sayısal verileri tırnak içine almadan yazıyoruz
else begin
if (Self.Fields[I].IsBlob = TRUE)
then Dosya.Write( TQ('') ) // CSV formatı blob / binary dataları desteklemez...
else Dosya.Write( TQ(Self.Fields[I].AsString) ); // Metinsel ifadeler ve formatlı veriler tırnak içine alınmak zorunda (CSV formatı gereği...)
end;
if (I < Self.FieldCount - 1)
then Dosya.Write( aAyrac ) // Hücrelerin arasını açıyoruz
else Dosya.WriteLine; // Yeni bir satıra geçiyoruz...
end;
Self.Next; // Sonraki recorda geçiyoruz
end;
finally
FreeAndNil(Dosya); // Nihayetinde Çöpümüzü temizledik...
end;
finally
if (Self.BookmarkValid(Imlec) = TRUE) then Self.GotoBookmark(Imlec); // Nihayetinde Datasetteki satır pozisyonumuzu ilk bulduğumuz yere geri çektik...
Self.EnableControls; // Nihayetinde Görsel Senkronizasyonu yeniden açtık
end;
end;
end.
Kullanımı da şu şekildedir;
uses Helpers_Data;
//...
DataSet.ExportToCSV ( 'C:\EXPORTS\TEST.CSV', TEncoding.UTF8, ';' );
UTF8 kodlamasını kullanarak arap, kiril, japon alfabesi gibi farklı karakter kodlarına sahip veri tipleri de düzgün aktarılmış olacaktır.
Yorum yapılmamış