29-08-2017, Saat: 14:09
(Son Düzenleme: 04-09-2017, Saat: 10:32, Düzenleyen: uparlayan.
Sebep: İmla düzeltmeleri
)
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.
Kullanımı da şu şekildedir;
UTF8 kodlamasını kullanarak arap, kiril, japon alfabesi gibi farklı karakter kodlarına sahip veri tipleri de düzgün aktarılmış olacaktır.
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.
YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa