Dinamik Tablo Oluşturma, Runtime Alan Kontrolü ve Düzenleme

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

- Adres bilgilerinizi özel mesajla bildirmeniz daha doğru olurdu ancak Avukat olduğunuza göre adınıza bir sakınca yoktur. :o

- Evet doğrudur eşim avukat. Ben de kendisi için UYAP destekli bir yazılım hazırlamayı planlıyorum. Şu an yeni bebeğimiz olduğundan askıya aldım.

- Veritabanınıza dönemsel yeniliklere göre tablo, alan ekleniyor ve/veya alan boyutları değiştirilmesi gerekiyorsa bu yukarda verdiğimiz sistem zaman ve emek tasarrufu sağlayacaktır. Ancak bunu kavramsal olarak değerlendirip kendi veritabanınıza uyarlamanız gerekli.

- Veritabanınızdaki her tablo için müstakil birer TipTanimlari_Tablo1( Liste:TStrings ); şeklinde belirttiğimiz procedure oluşturmanız gerekiyor. Bunu henüz anlamadıysak, buraya TABLO adını ve VERI ALANLARIN'dan örnekler yazarsanız sizin için bir örnek hazırlarız böylece daha anlaşılır olacaktır.

- Sistem karmaşık görünen bir yapı sergiliyor bunu kabul ediyorum. Ancak kısım kısım incelerseniz hiyerarşik düzeni görebilir ve adapte olabilirsiniz.
Resim
Resim ....Resim
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Mesaj gönderen sabanakman »

adnansirca yazdı:...Tabi mağdur olunca çıldırıp bağırmak sizi tatmin etmiyor. Bu durumda çözüm arıyorsunuz. Ve ben de bir proje hazırlayarak hukuki meseleler bakımından hukukçulara yardımcı olmaya çalışıyorum. Bir programcı olarak bunu ne ölçüde tasvip edersiniz açıkçası benim için önemli......
Hocam son haddine kadar arkanızda olacağımızı bilmenizi isterim. Çünkü, bazı programları sözüm ona kopya koruması altına almak adına belirli dönemlerde birden çalışmaz hale gelmektedir ve ne hikmetse bu da kullanıcının en önemli dönemine denk getirildiği için bir bakıma kullanıcyı buna mahkum bırakmaktadırlar. Bu durum hiç etik olmadığı için buradan sizin yaptığınız bu davranış herkes tarafından onay alacaktır. Eğer bu tür programları yapan şahıslar dönemsel güncellemeler için yıllık bakım sözleşmesini talep etseler o zaman yaptıkları etik olurdu ama bu şekilde kullanıcıyı kalbinden vurmak bana çok alçakça gelmektedir. Benzeri bir durumu öğretmenlik yaparken yaşamıştım. Ders çizelgesi hazırlama programı satın alınmış ve o da nesi. Ertesi yıl okulların açıldığı zaman aynı program aynı sistemde lisans şifresi istiyordu. Neyse ki başka bir program vardı da işimizi o programla halletmiştik. Ben de orada tıpkı sizin gibi ücretsiz çok iyi bir böyle proje yapmaya karar vermiştim ama nasip değilmiş. Bir türlü yeterli boş zamanı yakalayamadım. Gerçi şu aralar var ama artık o boş zamanlarımda bilgisayarlardan kaçar oldum :oops: .
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
adnansirca
Üye
Mesajlar: 135
Kayıt: 14 Kas 2005 12:24

Mesaj gönderen adnansirca »

Benim yaşadığım sıkıntıyı elbette çoğunuz yaşamışsınızdır. Bu nedenle destek veren tüm arkadaşlara ve site grubuna teşekkürlerimi sunuyorum. Bu site hakikaten kendi konusunda çok faydalı bir paylaşım alanı.

Sayın ARMAN veritabanımdaki tabloların yapısı ile ilgili size bir adres versem inceleyebilirseniz makbule geçer.
Projemin derlenmiş ilk hali(ki ben buna ilkel hali diyorum)
Türk Hukuk Sitesi 'nde yayınlamıştım. Bir sonraki hali ise
http://peyamiaydogdu.blogspot.com/ da bulunmaktadır.
Şu anda burada yayında. İndirme linki de mevcut. Söz konusu kullanılan veritabanında HukukAna isimli ana tablomun ilk hali de mevcut. Veritabanıma sonradan yeni tablolar ve alanlar ekledim. Şimdi benim uğraştığım mesele önceden yayınlamış olduğum veritabanına (ve burası çok önemli ki : içindeki bilgilere) herhangi bir zarar vermeden programın web üzerinden güncellemesini yaptırmak. Çünkü dağıtmaya başladıktan sonra bu programı kullanmaya başlayanlar oldu. Tabi verilerine bir zarar gelmemesi için bu çabayı sarfediyorum.
Programın şu andaki hali ile yayınladığım ilk hali arasında bir hayli fark var. Ben kendi sistemimde sorunsuz bir şekilde kullanabiliyorum. Acces in içinden tablolarıma müdahale edebiliyorum. Ancak diğer meslektaşlarıma da son versiyonu dağıtmak istiyorum. İstanbul'daki meslektaşların ofisine giderek bunu hallediyorum gerçi ancak Türkiye genelinde bir çok meslektaşım programı kullanmaya başlamış. Beni arayıp sorunlarını ve eksiklikleri dile getiriyorlar ve buna göre de düzenleme yapıyorum. Ancak mevcut düzenlemelerin ardından bu son haliyle programı dağıtırsam bu kerre access veritabanını kullanmayı bilen birisi olacak ki alan eksik vb... hatalarla karşılaşmasın. Öte yandan veritabanımdaki düzenlemeleri bir liste halinde benioku dosyalarına aktarıp düzenleme yöntemini de açıklıyorum. Buna rağmen yapamayan arkadaşlar oluyor. Bu sebeple de otomatik kontrol sistemini eklemem gerekiyor ki meslektaşlar da mağdur olmasın.

Eşiniz de UYAP projesi nedeniyle sıkıntı yaşıyordur sanırım. Bu proje hayata girdikten sonra İstanbul da iş yapamaz olduk. Bir de satın alınan programların UYAP uyumludur-Sorunsuz çalışır gibi aldatmalı yönleriyle karşılaşınca moralinizin düzgün olması mümkün değil.
Ben kendi projemde UYAP ile entegreli bir düzenleme yapıyorum şu anda. Bir süre sonra kullanmaya başlarım sanırım. Bu konuda siz de proje hazırladığınızı belirtmişsiniz. Size uyap entegreli bir veritabanı göndereyim. Bu veritabanı yapısı aydınlatıcı olacaktır. Bunun dışında her zaman da yardımcı oluruz.
Veritabanı linki : http://d.turboupload.com/d/2083753/IcraUYAP.rar.html
Şifresi beni oku dosyasında...
Çalışmalarınızda başarılar diliyorum....[/url]
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

Merhaba

- 46 adet tablon varmış. Sana referans olsun diye bunlardan ilk üçü için bir kurgu hazırladım.

Rapidshare linki şurada indirip deneyebilirsiniz.
// Kod ZIP paketi de güncellendi...
http://rapidshare.com/files/62731925/UY ... tabani.zip

:idea: - Proje veritabanı yoksa yenisini oluşturur.
:idea: - Veritabanı içinde tablolardan hangisi veya hangileri yoksa onları da oluşturur.
:idea: - Tablo tanımında örneğin 50 olan text uzunluğunu 100 yaptınız diyelim, bunu otomatik olarak anlar ve düzeltir.
:idea: - Mevcut verilere zarar gelmeden dinamik bir şekilde işlem yürür.

- Kabul etmek gerek kolay bir oluşum değildir. Sistemi herkes anlamayabilir. Bunu saygıyla karşılarız. Diğer yandan kavrayacak durumda olanlar için bu başlığı okuyanlardan bu konu artık iyice pekişecektir diye değerlendiriyorum. Tekrar ediyorum temel amaç tablo oluşumunu ve yönetimini olabildiğince kolaylaştırmaktır..

- Tanımını ekleyeceğin her tablonun adını şu satıra eklemen gerekiyor.

Kod: Tümünü seç

const
  Tablolar: array[1..3] of string = ('Avukatlar', 'Borclar', 'Borclar_Default');
- Tanımını eklediğin tablonun Trafikte yer alması için ARRAY'a eklediğin sıradaki CASE satırına da yani aşağıdaki yere de eklemen gerekiyor.

Kod: Tümünü seç

//-----------------------------------------------------------------------------
// Trafik Kontrolü...
//-----------------------------------------------------------------------------
procedure StrucTrafik(Tablo: string; KomutListesi: TStrings);
var
  Sayac,
    idx: Integer;
begin
...
...
...
...
  case idx of
    01: // 'Avukatlar'
      Struc_Avukatlar(KomutListesi);
    02: // 'Borclar'
      Struc_Borclar(KomutListesi);
    03: // 'Borclar_Default'
      Struc_BorclarDefault(KomutListesi);
  end; // Case
...
...
...
- Gerisini bu komutlar otomatik halledecektir. Yani tablo yoksa oluştur, varsa alanları sına ve eksikleri tamamla vs.

Kod: Tümünü seç

Uses ComObj;

Const
  xBaglanti = 'Provider=Microsoft.Jet.OLEDB.4.0;'
            + 'Data Source=%s;'
            + 'Jet OLEDB:Database Password=%s;';
  Password  = 'error';

const
  Tablolar: array[1..3] of string = ('Avukatlar', 'Borclar', 'Borclar_Default');

const
  FieldTanimiPriKey     = '%s %s(%d) CONSTRAINT idxUYAP PRIMARY KEY,';
  FieldTanimiPriKeyDate = '%s %s     CONSTRAINT idxUYAP PRIMARY KEY,';
  FieldTanimi     = '%s %s(%d),';
  FieldTanimiDate = '%s %s,';

Var
  xDBDosya : TFileName;
// Motor fonksiyonlarımızın başlangıcı .......
//-----------------------------------------------------------------------------

//--- Veritabanı (.mdb) oluşturma ---
Procedure VeritabaniOlustur( Hedef:String );
var
  cat    : OleVariant;
begin
  cat := CreateOleObject('ADOX.Catalog'); // Uses ComObj
  If FileExists(Hedef) Then DeleteFile(Hedef);
  cat.Create(Format(xBaglanti, [Hedef, Password]));
  cat := Unassigned;                      // Uses Variants
end;

Procedure Struc_Avukatlar( Liste:TStrings );
begin
  With Liste do begin
    Clear;
    Add('CREATE TABLE Avukatlar (');
    Add(Format(FieldTanimiPriKeyDate, ['AID',     'AutoIncrement']));
    Add(Format(FieldTanimi,     ['AAd',           'Text',     50]));
    Add(Format(FieldTanimi,     ['ASoyad',        'Text',     50]));
    Add(Format(FieldTanimi,     ['AKimlikNo',     'Text',     20]));
    Add(Format(FieldTanimi,     ['ACinsiyet',     'Text',     10]));
    Add(Format(FieldTanimi,     ['ASicilNo',      'Text',     20]));
    Add(Format(FieldTanimi,     ['ABaroNo',       'Text',     50]));
    Add(Format(FieldTanimi,     ['AVergiDairesi', 'Text',    150]));
    Add(Format(FieldTanimi,     ['AVergiNo',      'Text',     20]));
    Add(Format(FieldTanimi,     ['AVTipi',        'Text',     10]));
    Add(Format(FieldTanimi,     ['ATBBNo',        'Text',     20]));
    Add(Format(FieldTanimi,     ['AAdres',        'Text',    250]));
    Add(Format(FieldTanimi,     ['AIl',           'Text',     20]));
    Add(Format(FieldTanimi,     ['AIlce',         'Text',     20]));
    Add(Format(FieldTanimiDate, ['AKurumAvukati', 'Logical',   0]));
    Add(Format(FieldTanimiDate, ['ASigortali',    'Logical',   0]));
    Add(Format(FieldTanimiDate, ['ABorcluVekili', 'Logical',   0]));
    // Son virgülü silmek lazım,
    Liste[Liste.Count - 1] := Copy(Liste[Liste.Count - 1], 1, Length(Liste[Liste.Count - 1]) - 1);
    Add(')');
  end;
end;

Procedure Struc_Borclar( Liste:TStrings );
begin
  With Liste do begin
    Clear;
    Add('CREATE TABLE Borclar (');
    Add(Format(FieldTanimiPriKeyDate, ['BID',     'AutoIncrement']));
    Add(Format(FieldTanimiDate, ['BTakipID',      'Integer', 0 ]));
    Add(Format(FieldTanimi,     ['BSebep',        'Text',   50 ]));
    Add(Format(FieldTanimiDate, ['BVadeTarih',    'Date',    0 ]));
    Add(Format(FieldTanimiDate, ['BGercekTutar',  'Currency',0 ]));
    Add(Format(FieldTanimiDate, ['BTutar',        'Currency',0 ]));
    Add(Format(FieldTanimi,     ['BTutarTip',     'Text',   20 ]));
    Add(Format(FieldTanimi,     ['BFaiz1',        'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BFaiz2',        'Text',   50 ]));
    Add(Format(FieldTanimiDate, ['BOran1',        'Currency',0 ]));
    Add(Format(FieldTanimiDate, ['BOran2',        'Currency',0 ]));
    Add(Format(FieldTanimiDate, ['BOran3',        'Currency',0 ]));
    Add(Format(FieldTanimiDate, ['BOran4',        'Currency',0 ]));
    Add(Format(FieldTanimiDate, ['BOran5',        'Currency',0 ]));
    Add(Format(FieldTanimiDate, ['BOran6',        'Currency',0 ]));
    Add(Format(FieldTanimiDate, ['BSabit',        'Currency',0 ]));
    Add(Format(FieldTanimiDate, ['BAciklama',     'Memo',    0 ]));
    Add(Format(FieldTanimi,     ['BVeri1',        'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BVeri2',        'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BVeri3',        'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BVeri4',        'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BVeri5',        'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BVeri6',        'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BOtomatik',     'Text',    2 ]));
    // Son virgülü silmek lazım,
    Liste[Liste.Count - 1] := Copy(Liste[Liste.Count - 1], 1, Length(Liste[Liste.Count - 1]) - 1);
    Add(')');
  end;
end;

Procedure Struc_BorclarDefault( Liste:TStrings );
begin
  With Liste do begin
    Clear;
    Add('CREATE TABLE Borclar_Default (');
    Add(Format(FieldTanimiPriKeyDate, ['BID',  'AutoIncrement']));
    Add(Format(FieldTanimi,     ['BT1',        'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BT2',        'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BSebep',     'Text',   50 ]));
    Add(Format(FieldTanimiDate, ['BVadeTarih', 'Date',    0 ]));
    Add(Format(FieldTanimiDate, ['BTutar',     'Currency',0 ]));
    Add(Format(FieldTanimi,     ['BTutarTip',  'Text',   20 ]));
    Add(Format(FieldTanimi,     ['BFaiz1',     'Text',   50 ]));
    Add(Format(FieldTanimi,     ['BFaiz2',     'Text',   50 ]));
    Add(Format(FieldTanimiDate, ['BAciklama',  'Memo',    0 ]));
    // Son virgülü silmek lazım,
    Liste[Liste.Count - 1] := Copy(Liste[Liste.Count - 1], 1, Length(Liste[Liste.Count - 1]) - 1);
    Add(')');
  end;
end;


//-----------------------------------------------------------------------------
// Trafik Kontrolü...
//-----------------------------------------------------------------------------
procedure StrucTrafik(Tablo: string; KomutListesi: TStrings);
var
  Sayac,
    idx: Integer;
begin
  KomutListesi.Clear;
  idx := -1;
  for Sayac := 1 to High(Tablolar) do
    if Tablolar[Sayac] = Tablo then begin
      idx := Sayac;
      Break;
    end;

  case idx of
    01: // 'Avukatlar'
      Struc_Avukatlar(KomutListesi);
    02: // 'Borclar'
      Struc_Borclar(KomutListesi);
    03: // 'Borclar_Default'
      Struc_BorclarDefault(KomutListesi);
  end; // Case
end;

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

procedure TForm1.BitBtn1Click(Sender: TObject);
Var
  Dizin : String;
begin
  With TOpenDialog.Create(Nil) do begin
    Filter := 'MDB veritabanı *.mdb|*.mdb';
    If Execute then begin
       // elle giriş yapılırsa uzantısı girilmezse veya hatalı girilirse...
       // garantiye almak için uzantıyı (.mdb) olarak değiştirdik...
       xDBDosya := ChangeFileExt(FileName, '.mdb');
       Dizin    := ExtractFilePath(xDBDosya);
       If Length(Dizin) > 40 then Dizin := Format('%s..\..\..%s\', [
         Copy(Dizin, 1, 20),
         Copy(Dizin, Length(Dizin)-21, 20) ]);
       Edit1.Text := Dizin + ExtractFileName(xDBDosya);
    end;
    Free;
  end;
end;

Procedure TabloKontrol( DBDosya:TFileName; AdoQuery1, AdoQuery2 : TAdoQuery );
// -----------------------------------------------------------------------------
// Tablo varsa eksik veya değişiklik varsa tamamla, yoksa yenisini oluştur...
// İki adet TAdoQuery (AdoQuery1 ve AdoQuery2) ihtiyaç duyulur...
// Birisi kontrol diğeri uygulama içindir...
// AdoQuery1 EXECSQL için kullanılacak
// AdoQuery2 sadece Tablo Alan listesini elde ederek kontrol için.
// -----------------------------------------------------------------------------
Const // komut seti için hazırladığım format tanımlarım
  FieldSil        = 'ALTER TABLE %s DROP %s';
  FieldEkle       = 'ALTER TABLE %s ADD %s %s(%d)';
  FieldEkleDate   = 'ALTER TABLE %s ADD %s %s';
  FieldDegis      = 'ALTER TABLE %s ALTER COLUMN %s %s(%d)';
  FieldDegisDate  = 'ALTER TABLE %s ALTER COLUMN %s %s';
Var
  TabloListe,
  Liste           : TStringList;
  //TabloAdi        : String;

  i, j            : Integer;
  Alan, Tip       : String;
  Uz              : Integer;
  Gecici          : String;
begin
  If DBDosya = '' then begin
    MessageDlg('Veritabanı henüz seçilmemiş...', mtError, [mbAbort], 0);
    Exit;
  end;
  // 1. Aşama : Veritabanı (katalog dosya) fiziksel olarak Yoksa !!!
  //            Yeni bir tane (.mdb) katalog create edilir...
  //----------------------------------------------------------------------------
  If NOT FileExists(DBDosya) then VeritabaniOlustur(DBDosya);

  // 2.Aşama : Tablolar tek tek kontrol edilecek.
  //           Olmayan varsa yenisi oluşturulacak...
  //----------------------------------------------------------------------------
  If NOT AdoQuery1.Connection.Connected then begin
    AdoQuery1.Connection.ConnectionString := Format(xBaglanti, [DBDosya, Password]);
    AdoQuery1.Connection.LoginPrompt := False;
  end;
  Liste      := TStringList.Create;
  TabloListe := TStringList.Create;
  // var olan Tablo listesini alıyoruz...
  AdoQuery1.Connection.GetTableNames( TabloListe, False );
  For i := 1 to High(Tablolar) do begin
    StrucTrafik( Tablolar[i], Liste );
    If TabloListe.IndexOf( Tablolar[i] ) < 0 then
    begin // Bu tablo veritabanında yok, yenisini oluşturucaz...
          // Yani "Create Table" olayı işleyecek...
      // Sayac sıradaki tablo için "Create Table" SQL text'ini Liste'ye alıyoruz.
      AdoQuery1.SQL.Text   := Liste.Text;
      AdoQuery1.ExecSQL;
    end else begin // Tablo var ancak alan isimleri doğru mu ? Eksik gedik var mı ?
      Liste.Delete(0); // ilk satırı sildik. Hani Create table olanı.
      Liste.Delete(Liste.Count-1); // son satırı sildik. Hani parantez olanı.
      Liste[Liste.Count-1] := Liste[Liste.Count-1] + ','; // son satıra virgül ekliyoruz.
      // Bu eklenen virgül tüm satırlar tutarlı olsun diye. Çünkü parse edicez
      // ederken de satır sonundaki virgülden kerteriz alıcaz...

      // Artık elimizde alan isim ve tipleri var.
      // Yapılacak işlem bu satırlar String Parse edilerek
      // ------------------------
      //  1. Eksik alan varsa eklenir.
      //  2. Uzunluk değişikliği yapılmışsa güncellendir.
      //  3. Tip değişikliği yapılmışsa ( Böyle bir durum henüz yok )

      // Field Listesi için var olan Tablo boş olarak açılıyor...
      // AlanListe stringlist'ine aktarılıyor...

      AdoQuery2.SQL.Text := 'SELECT * FROM '+ Tablolar[i] +' WHERE 1=0';
      AdoQuery2.Active   := True;

      // Kontrol edilecek alanlar Liste stringlist'inden sırayla kontrol edilecek.
      For j := 0 to Liste.Count-1 do begin
        Gecici := Trim( Liste[j] );

        // İlk boşluğa kadar olan kısım Alan Adı oluyor...
        Alan   := Copy(Gecici, 1, Pos(' ', Gecici)-1);
        System.Delete( Gecici, 1, Length(Alan) );
        Gecici := Trim(Gecici);

        // Parantez varsa parantezin önündeki, yoksa son virgülün önündeki Tip oluyor....
        Tip  := Gecici;
          If Copy( Tip, 1, Pos('(', Tip)-1 ) <> ''
            then Tip := Copy( Tip, 1, Pos('(', Tip)-1 )
            else Tip := Copy( Tip, 1, Pos(',', Tip)-1 );
          System.Delete( Gecici, 1, Length(Tip) );
          Gecici := Trim(Gecici);
        // Parantez varsa parantez içeriği Uzunluk, yoksa uzunluk 0 oluyor....
        If ( Gecici <> '' ) AND ( Gecici[1] = '(' )
          then Uz := StrToInt(Copy(Gecici, 2, Pos(')', Gecici)-2))
          else Uz := 0;

        // Bulduğumuz alan adını Tablodan kontrol ediyoruz...
        If AdoQuery2.FieldList.IndexOf(Alan) < 0 then begin
          // Alan yok ekliyoruz...
          If Uz = 0
            then AdoQuery1.SQL.Text := Format(FieldEkleDate, [Tablolar[i], Alan, Tip ])
            else AdoQuery1.SQL.Text := Format(FieldEkle,     [Tablolar[i], Alan, Tip, Uz ]);
          AdoQuery1.ExecSQL;
        end else begin
          // Alan var ancak Uzunluk aynı mı ? kontrol ediyoruz.
          If (AdoQuery2.FieldByName(Alan).Size <> Uz) then begin
            If (Tip <> 'Currency') then begin
              // Özel bir durum var. AUTOINC bir alan olacaksa o zaman eski alanı silip
              // yeniden oluşturucaz yoksa sadece düzelticez..
              If (UpperCase(Tip) = 'AUTOINCREMENT') then begin
                // Alan düşürülür, AutoInc alan baştan eklenir...
                // Alanı silme
                AdoQuery1.SQL.Text := Format(FieldSil, [Tablolar[i], Alan]);
                AdoQuery1.ExecSQL;
                // Yenisini ekleme..
                If Uz = 0
                  then AdoQuery1.SQL.Text := Format(FieldEkleDate, [Tablolar[i], Alan, Tip ])
                  else AdoQuery1.SQL.Text := Format(FieldEkle,     [Tablolar[i], Alan, Tip, Uz ]);
                AdoQuery1.ExecSQL;
              end else begin
                // Sadece Düzeltme
                If Uz = 0
                  then AdoQuery1.SQL.Text := Format(FieldDegisDate, [Tablolar[i], Alan, Tip ])
                  else AdoQuery1.SQL.Text := Format(FieldDegis,     [Tablolar[i], Alan, Tip, Uz ]);
                AdoQuery1.ExecSQL;
              end;
            end; // Currency ise zaten 4 olacaktır.
          end; // Alan Uzunluk değişiklik kontrolü
        end; // Alan kontrolü bloğu
      end; // Alan isimleri için çalışan For döngüsü
    end;
  end;
  TabloListe.Free;
  Liste.Free;
end;

- Burada da uygulaması görülüyor... Bir forma iki tane TButon bir de TEdit koydum.

Kod: Tümünü seç

procedure TForm1.FormCreate(Sender: TObject);
begin
  AdoConnection1.LoginPrompt := False;
  AdoQuery1.Connection := AdoConnection1;
  AdoQuery2.Connection := AdoConnection1;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
Var
  Dizin : String;
begin
  With TOpenDialog.Create(Nil) do begin
    Filter := 'MDB veritabanı *.mdb|*.mdb';
    If Execute then begin
       // elle giriş yapılırsa uzantısı girilmezse veya hatalı girilirse...
       // garantiye almak için uzantıyı (.mdb) olarak değiştirdik...
       xDBDosya := ChangeFileExt(FileName, '.mdb');
       Dizin    := ExtractFilePath(xDBDosya);
       If Length(Dizin) > 40 then Dizin := Format('%s..\..\..%s\', [
         Copy(Dizin, 1, 20),
         Copy(Dizin, Length(Dizin)-21, 20) ]);
       Edit1.Text := Dizin + ExtractFileName(xDBDosya);
    end;
    Free;
  end;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
  // Uygulama....
  TabloKontrol(xDBDosya, AdoQuery1, AdoQuery2);
end;

// EDIT // Düzeltme //

Tablolar string değişkeni yerine TabloAdi ifadesi olarak değiştirildi. Bu ilk örnekten dönüşüm yapıldığından unutulmuş..
En son mrmarman tarafından 15 Eki 2007 06:05 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Resim
Resim ....Resim
adnansirca
Üye
Mesajlar: 135
Kayıt: 14 Kas 2005 12:24

Mesaj gönderen adnansirca »

Hocam bu detaylı ilgi için teşekkürlerimi sunuyorum. Kodları henüz uygulamadım ama incelediğim kadarıyla benim başkaca da bir şey yapmama gerek kalmıyor. Siz tamamını benim için halletmişsiniz.

Eren ARMAN için de gözünüz aydın diyor ve Allah hayırlı evlat olarak yetiştirsin diyorum. Bu kısımlar özel olsa da forumdaki arkadaşların da bunu anlayışla karşılayacaklarını düşünüyorum.

UYAP destekli bir proje hazırlayacağınız zaman hukuki tüm desteklerimi sunacağımı da bilmenizi isterim.

İyi çalışmalar..

MUTLU BAYRAMLAR, size ve tüm forum katılanlarına ve grubuna.....
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

Memnun oldum.

- İyi dilekleriniz için teşekkürler. Sizlerin de bayramını kutlarım.
Resim
Resim ....Resim
hgunes
Üye
Mesajlar: 27
Kayıt: 01 Nis 2007 03:40
Konum: Çorum

Mesaj gönderen hgunes »

s.a
Hepinize iyi bayramlar.

sn @mrmarman bu son derece faydalı çalışmadan dolayı sizi kutluyorum.
Ellerinize sağlık. Ancak kullanıcıların sizin hesaba hiç katmadığınız
aklınızdan bile geçmeyen bir hatayı üzerinde o kadar çalışmış olmanıza rağmen ortaya çıkardıklarına siz benden daha çok şahit olmuşsunuzdur.

Kodları denemedim, ancak incelediğim kadarıyla temel mantık olarak
vt'da mevcut tabloları, alanları ve alan tipleri ile sizin kod içinde
sakladığınız vt, alan ve alan tipi bilgilerini karşılaştırıp eksik tablo ve
alanları oluşturuyor, farklı tipteki alanları yeni duruma göre güncelliyor.

Buraya kadar hiçbir sorun yok. Ben dikkatsiz bir kullanıcı olarak sizin tablo kontrol kodunuzu içeren ama versiyonu eski olan programla daha yeni versiyonlu programla güncellenmiş bir veritabanını açtığımda kendisi eski olan program veritabanını eski, kendini ise yeni algılayacağından haliyle veritabanını kendi kodunda saklı yapıya dönüştürecektir. Bu durum çoğu zaman yeni versiyonda veritabanını tekrar açmakla düzelebilecekken, eğer kontrol kodunu bu haliyle kullanan ek olarak tablo verilerinde kendi yazdığı kodlarla özel değişiklikler yapan programcıların verilerinin geri dönülemez şekilde kaybına da sebep olabilir. Tabi bunlar tamamen hayal ürünü, ancak olmayacak şeyler de değil. Kullanıcı programın versiyonuna dikkat etmeyebiliyor.

Çözüm vt versiyon bilgisini içeren bir tablo eklemek, vt versiyonunu bu
tablodan okutup eski ise tablo kontrolü yapmak ve yeni versiyonu tabloya
yazdırmak. Versiyon tablosu olmayan bir vt açıldığında ise ver. tablosunun
bir sefer oluşturulması yeterli olacaktır.

Eksik olan her bir tablo için (sıfırdan oluşturuyorsak tüm tablolar için)
CREATE komutunu içeren listeyi döndüren ayrı ayrı procedure'ler
yazılması gerektiği, tablo listesinin de bir dizi'de tutulduğu görülüyor.
Delphi'den Access vt'na bağlanma ve üzerinde çalışma alan ve tip
sorgulaması konusunda bilgim yeterli olsaydı vt'nını okuyup CREATE
yordamını bir text yada ini dosyaya yazan bir utility oluşturur, tablo
kontrolü esnasında tip tanımlamalarını bu dosyadan okutur (tablo listesi
için de aynı şey) böylece veritabanı her değiştiğinde kontrol koduna
ekleme yapmaya gerek duymazdım. Bu da ikinci önerim.

Kolay gelsin.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

@hgunes

- Kaygını sadece öngörü bağlamında kabul edebilirim. :roll: Denemdiğin için faydasını görmedin, zararından korkuyorsun. :wink:
@hgunes yazdı:Kodları denemedim, ancak incelediğim kadarıyla temel mantık olarak
vt'da mevcut tabloları, alanları ve alan tipleri ile sizin kod içinde
sakladığınız vt, alan ve alan tipi bilgilerini karşılaştırıp eksik tablo ve
alanları oluşturuyor, farklı tipteki alanları yeni duruma göre güncelliyor.
- Evet kurgu aynen bunun üzerine.
Ben dikkatsiz bir kullanıcı olarak sizin tablo kontrol kodunuzu içeren ama versiyonu eski olan programla daha yeni versiyonlu programla güncellenmiş bir veritabanını açtığımda kendisi eski olan program veritabanını eski, kendini ise yeni algılayacağından haliyle veritabanını kendi kodunda saklı yapıya dönüştürecektir.


- Sizin tablo adınız ile aynı tablo ise bu söylediğiniz geçerlidir. Ayrıca bu kurgu geliştirmeye yönelik bir yapı sergiliyor. Veri alanlarını olduğundan daha küçük uzunluklara dönüştürmediğiniz sürece veri kaybı meydana gelmez ki ? Burada konu programcılık becerisinin size ne kadar hizmet edip etmeyeceğiyle ilgili.

- Sürekli sürüm güncellemesi yaptığınız bir projeye başladığınızda bu yapıya ne kadar ihtiyacınız olduğunu anlayacaksınız. Şimdi en iyisi siz bunu kullanmayın. :lol: :lol: :lol:

- Şu an DivXTurk adında bir projem var. 8) Proje bundan 7 yıl önce doğdu. Veritabanı olarak 1 tablo ve 50 alan gibi küçük yapı sergiliyordu. Zamanlar bugünkü halini aldı. Yeni tablolar eklendi, alan tipleri / uzunlukları değişti ancak son kullanıcı bunların hiçbirini farketmeden mevcut verileri kaybolmaksızın yeni gelişkin veritabanına geçiş otomatik olarak kendiliğinden gerçekleşti. Bu yapı bu ve benzeri durumlar için kurulmuştur. :idea:

- Hedefler ve Amaçlar belli ise buna benzer bir yapı hayat kurtarıcıdır. Kullanıp kullanmamakla herkes özgür. Geçtiğimiz günlerde buna ilişkin gelen bazı talepler üzerine burada kodları yayınladık.

- Bu yapıyı STRUCTURES.PAS isimli bir unit'de tutuyoruz. Programın herhangi bir yerinde herhangi bir alan ile ilgili bir çalışma olacaksa bu unitten merkezi olarak faydalanıyoruz. Bu bize proje içerisinde tek noktadan müdahale ile tüm projenin dinamik yapıya bürünmesini sağlıyor.

- Yarın başka bir projeye soyunmak istersek ne yapıyoruz ? Bu structures.pas dosyasını alıp oraya kopyalıyor sadece text bazında dilediğimiz alan isim ve tiplerini değiştiriyoruz o kadar. Programın veritabanı altyapısı anında hazır. Kendinden servis veen bir yazılımınız olması mı daha iyi yoksa bağımsız servis yazılımına ihtiyacı olan bir yazılım mı :?: Burada kendi kendini servis eden bir yapı sergiliyoruz.

- Programcılık bilinçli yapılan bir iştir. Bu işi olması gibi yaptığımızı değerlendirirsek biz delphiden değil delphi bizden korksun.. Son sözüm budur. :lol: :lol: :lol:
Resim
Resim ....Resim
Kullanıcı avatarı
haydarxxx
Üye
Mesajlar: 668
Kayıt: 09 May 2005 11:31
Konum: izmir

Mesaj gönderen haydarxxx »

mrmarman hocam makaleniz şiir gibi vallahi :lol:
Veritabanı access e geçesi geliyor insanın :) ama malum Firebird kullanıyoruz ben yine aynı istek ve ricamı tekrarlayacağım çünkü böyle bir makaleyi :shock: dört gözle bekliyorum hergün forumu kontrol ediyorum.Şu işin firebird makalesini yayınlamanız harika olcak.
Şu an DivXTurk adında bir projem var. Proje bundan 7 yıl önce doğdu. Veritabanı olarak 1 tablo ve 50 alan gibi küçük yapı sergiliyordu. Zamanlar bugünkü halini aldı. Yeni tablolar eklendi, alan tipleri / uzunlukları değişti ancak son kullanıcı bunların hiçbirini farketmeden mevcut verileri kaybolmaksızın yeni gelişkin veritabanına geçiş otomatik olarak kendiliğinden gerçekleşti. Bu yapı bu ve benzeri durumlar için kurulmuştur.
Programlar statik olmuyor lakin her projede bir takım değişiklikler vt olmak zorunda kalıyor dolayısı ile bu makaleniz her derde deva olacak

İyi Bayramlar Dilerim
hgunes
Üye
Mesajlar: 27
Kayıt: 01 Nis 2007 03:40
Konum: Çorum

Mesaj gönderen hgunes »

@mrmarman@
- Kaygını sadece öngörü bağlamında kabul edebilirim. Denemdiğin için faydasını görmedin, zararından korkuyorsun.
- Benimki tabiki bir öngörü. Ama size yönelik değil. Eminim ki bu kodları kullandığınız projeniz bu tür hata ihtimallerini kapsamlı olarak değerlendiriyordur.

- Benim niyetim bu kodları programlarında kullanacak özellikle deneyimsiz arkadaşları bu durumdan haberdar etmekti.

- Kaldı ki bu kod yapısının faydasızlığından ya da benim kullanıp kullanmayacağımdan asla sözetmiş değilim. Denememiş olmam fayda/zarar ilişkisi hakkında yorum yapmama engel değildir. Denemediğimi özellikle belirtmem de konuya ne kadar iyiniyetle yaklaştığımın göstergesidir. Mesaj sahibi siz olmanız nedeniyle sizin şahsınızda ama forum üyelerinin dikkatine yönelik yaptığım bu yapıcı eleştiri(öneri mi deseydim) gereksiz bir yanlış anlaşılmaya sebep oldu. Mesajımı hiç dikkate almayıp yorum dahi yapmasaydınız. İşte o zaman bozulurdum.

Bundan sonra yazacaklarım genel olarak algılansın lütfen. :lol:

Deniyor ki :
- Yarın başka bir projeye soyunmak istersek ne yapıyoruz ? Bu structures.pas dosyasını alıp oraya kopyalıyor sadece text bazında dilediğimiz alan isim ve tiplerini değiştiriyoruz o kadar. Programın veritabanı altyapısı anında hazır. Kendinden servis veen bir yazılımınız olması mı daha iyi yoksa bağımsız servis yazılımına ihtiyacı olan bir yazılım mı ? Burada kendi kendini servis eden bir yapı sergiliyoruz.
Ben de diyorum ki :
Eksik olan her bir tablo için (sıfırdan oluşturuyorsak tüm tablolar için)
CREATE komutunu içeren listeyi döndüren ayrı ayrı procedure'ler
yazılması gerektiği, tablo listesinin de bir dizi'de tutulduğu görülüyor.
Delphi'den Access vt'na bağlanma ve üzerinde çalışma alan ve tip
sorgulaması konusunda bilgim yeterli olsaydı vt'nını okuyup CREATE
yordamını bir text yada ini dosyaya yazan bir utility oluşturur, tablo
kontrolü esnasında tip tanımlamalarını bu dosyadan okutur (tablo listesi
için de aynı şey) böylece veritabanı her değiştiğinde kontrol koduna
ekleme yapmaya gerek duymazdım. Bu da ikinci önerim.
- Utility programı deyince kullanıcı bu programı illa ki kendi bilgisayarında vt güncellemesi yapacak ekstra bir servis yazılımı gibi çalıştıracak anlamı çıkmasın. Bu yardımcı yazılımı programcı kendisi için kullanacak. Niye? Çünki Bu program her tablo için koda eklenen Struc_XXTablosu yordamında oluşturulan sql kodunu bir text dosyaya yazacak, aynı zamanda tablo listesini de bu dosyaya yazacak. @mrmarman'ın kendi programında kurduğu dinamik yapıya benim bu önerim gerçekten eğreti gelebilir. Tabi ki herkes kullanıp kullanmamakta özgür!.

- Belki uzun cümleler kurdum. Bütün bunlar ondandır. Kısaca :
1. Struct_XXTablosu procedure'lerini koddan çıkart.
2. Tablo Listesini tutan diziyi koddan çıkart.
3. Struct_XXTablosu yordamının oluşturduğu CREATE tablo ve devamında gelen alan tip tanımlamalarını yani yazılması gereken SQL kodunu ve tablo listesini oluşturabilecek ve txt dosyaya yazabilecek bir yardımcı program hazırla. Bu yazılımla vt'yi okut txt dosyayı hazırla.
4. Kendi programında TabloKontrol yordamı içinde tablo listesini o txt dosyadan okut.
5. Döngü içinde ne zaman bir tabloya ait CREATE kodu lazım oldu. txt dosya orda okut ordan geri kalan karşılaştırma ve güncelleme işlemleri yapılsın.
6. Sizce hangisi daha dinamik ya da hangisi son kullanıcı için daha pratik. Varsayalım tablo yapısında bir değişiklik yaptınız ve kullanıcıya gönderdiniz. Aa bi de baktınız ki tabloda bir alanın uzunluğu sizin gönderdiğinizden farklı olmalıydı. Ne yapıyoruz, o meşhur utility programını kullanıp txt dosyayı tekrar oluşturuyoruz. Kullanıcıya gönderiyoruz. Ne oldu işi görüldü. Ne oldu iki ayağımız bi papuca girmedi. Final Setup sonra gitse de olur.

Maksadımı aştımsa affola. @mrmarman hakkını helal et. Karşılıksız, sadece paylaşım adına emeğini bizimle paylaştın. Meyve veren ağaç taşlanır. :lol:
adnansirca
Üye
Mesajlar: 135
Kayıt: 14 Kas 2005 12:24

Mesaj gönderen adnansirca »

Hocam;
Veritabanı hiç yoksa yeniden oluşturup tabloları da başarılı bir şekilde ceate ediyor. Ancak mevcut tabloda bir alan eksik ise
'ALTER TABLE deyiminde söz dizimi hatası' alıyorum.
SQL kodunu bir memoya aktarıp inceledğimde
AdoQuery1.SQL.Text > ALTER TABLE ADD AdliyeTel Text(50)
Yani tablo adını alamıyor ve bu nedenle de hata veriyor.
işin ilginç tarafı ilk bir kaç denememde çalışıyordu ama sonradan bu hatayı vermeye başladı. Kodların yapısını incelediğimde bir sorun görmedim.(Sizin kodlarınız). Hata bendeki delphinin güncel olmamasından mı kaynaklanıyor acaba.(Delphi 7 Enterprise- OS : Windows Vista Home Basic)
Kullanıcı avatarı
haydarxxx
Üye
Mesajlar: 668
Kayıt: 09 May 2005 11:31
Konum: izmir

Mesaj gönderen haydarxxx »

Hocam bende şunu merak ederek sorayım

Tabloya kod ile yeni bir alan ekledik,alan sildik yada alnın size değiştirdik verdiğniz kodlara nasıl bir ekleme yapılıyor.Örneğin
Avukatlar tablosuna AVergiDairesiAdı alanı ekledik

Kod: Tümünü seç

Add(Format(FieldTanimi,     ['AVergiDairesiAdı', 'Text',    150]));

diye yeni bir ekleme yaptığımda alter table deyiminde söz dizimi hatası alıyorum


Ekleyeceğimiz alanları create içindeki kod blok una ekleme yapılması yeterli değilmi.Yada çıkaracağımız alanları bu kod blok undan silmemiz yeterli değilmi.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

@haydarxxx

- Direkt kopyala yapıştır yaptığını farzederek yazıyorum. Türkçe harf kullandığından hata alıyorsundur. AVergiDairesiAdı yerine AVergiDairesiAdi olarak isimlendir.

@adnansirca

- Sizde de işlem için Tablo adı olarak boş geçiyor.

Kod: Tümünü seç

Const // komut seti için hazırladığım format tanımlarım 
  FieldSil        = 'ALTER TABLE %s DROP %s'; 
  FieldEkle       = 'ALTER TABLE %s ADD %s %s(%d)'; 
  FieldEkleDate   = 'ALTER TABLE %s ADD %s %s'; 
  FieldDegis      = 'ALTER TABLE %s ALTER COLUMN %s %s(%d)'; 
  FieldDegisDate  = 'ALTER TABLE %s ALTER COLUMN %s %s'; 
ALTER TABLE tabloadı ADD alanadi tip (uzunluk) şeklinde olacakken sizin kodda tablo adı boş / yok. Kodları kendinize göre dönüştürürken bir noktayı atlamış olmalısınız.
Resim
Resim ....Resim
adnansirca
Üye
Mesajlar: 135
Kayıt: 14 Kas 2005 12:24

Mesaj gönderen adnansirca »

@mrmarman;
hocam ben de sizin gibi düşünmüştüm. Bunun üzerine rapidshare e yüklediğiniz projeyi hiç değiştirmeden uyguladım.(Yalnızca exe yi çalıştırdım) Aynı hatayı sizin projede de verdi. Örneğin Borclar tablosundan bir alanı elle sildim. Sonra Tablolar Kontrol yaptım. Bu hatayı verdi. %s ifadesini boş geçiyor. Siz kendi projelerinizde bu hatayla karşılaştınız mı hiç.[/quote]
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

- Hakikaten doğru. İlk verdiğim kodda TabloAdi string değişkenine tablonun adını atıyordunuz. Daha sonra olayı tabloların döngü ile nasıl işlediğini size örnekliycem derken eskisi gibi kalmış.. Düzelttim.

- TabloAdi ifadesi geçen yerlere Tablolar ifadesi ile değiştirmeniz kafi. Ben yukardaki kodda da düzelttim. Rapidshare linkindekini de...
Resim
Resim ....Resim
Cevapla