1

Konu: Private datasession - form object ilişkisi

Merhaba fox üstadları,

formlarda private datasession kullanarak kendi içerisinde de multiuser yapmaya çalışıyorum.
Daha önce default session olan tüm formlar aralarında gereken bilgileri gönderebiliyordu...
örneğin;
Thisform.tarih.value = Main_menu.tarih.value diyerek yeni açılan formda Main_menu formundaki
tarih değerini öğrenerek geliyordu.
Ne zaman ki her formu datasession private yaptım bu bağlantı koptu..?
Main_menu  object not found hatası veriyor...
Araştırmalarım sonucu;  _screen.forms(x) bu formlardan birisi ve bunu kullanabiliyorum...Başka bir yöntemi var mıdır?

Diğer bir konuda ilk açılan start formunda ki bir temporary cursor'e diğer formlardan kayıt insert edilmesi gerekiyor..
Private datasession'lu formlarda bunu nasıl yaparız?

Fox'la kalın.
Saygılar

2

Re: Private datasession - form object ilişkisi

VFP'nun en keskin özelliklerinden biri Form'lar (Dataenvironmentler) arasında ilişkiyi kesmesidir. Forumda 2-3 sene önce tartışmıştık, şimdi bulamadım.
benim çözümüm şöyle:
Form1.datahazirla diye bir evente diğer form (Form2) için gerekecek datayı diske yazacak komut hazırlıyorum: SELE x,y,z FROM Form1data INTO DBF c:\geçici\geçicidata.dbf

Form2 içinden Form1 i çalıştırıp datay diske yazıp, Form2 tarafından okudukyan sonra siliyorum, şöyle birşeyler gibi:

Visual Fox Pro
* form2.DiğerformdanDataAl

DO Form1 NAME f1
f1.Hide
f1.datahazirla
f1.Release
SELE * FROM c:\geçici\geçicidata.dbf INTO CURS form2degereklidata
ERAS c:\geçici\geçicidata.dbf


XML ile de biryerlere yazıp diğer formdan okuyabilirsin

VFP9 SP2

3

Re: Private datasession - form object ilişkisi

Private datasession tablo/cursor disindaki baglanti kopusunu aciklamaz. Baska bir nedeni olmali. Cozumlerin en basiti bir form yonetici object kullanmak. Bu en basit haliyle acilan formlari bir array'de isimle tutar. Ornegin:

Visual Fox Pro
do form Birform


yerine:

Visual Fox Pro
formManager.OpenForm("BirForm")

*OpenForm

Visual Fox Pro
lparameters tcFormName

dimension this.aForms[alen(this.aForms,1)+1,2]
this.aForms[alen(this.aFroms,1),1) = m.tcFormName
do form (m.tcFormName) name this.aForms[alen(this.aFroms,1),2)

Visual Fox Pro
* GetFormRef

lparameters tcFormName
local lnRow
lnRow = ascan( this.aForms, m.tcFormName,1,-1,1,1+2+4+8)
if m.lnRow > 0
   return this.aForms[ m.lnRow, 2 ]
else
  return null
endif

gibi (bu hali kafadan, test edilmemis kod).

Private Datasession disina data cikarman gerektiginde, datanin miktarina gore, XML, array ya da tablo kullanabilirsin.

4

Re: Private datasession - form object ilişkisi

Formlar arasını şimdilik _screen.forms ile hallettim gibi..
Aşağıdaki function yöntemi ile:
dönüş integer değeri _screen.forms(x) 'deki x rakamını veriyor.

local form_id_number
form_id_number=form_obj("MAIN_MENU")
if form_id_number<>0
  Thisform.trh.value=_screen.forms(form_id_number).trh.value
endif

Function frm_obj(formun_adi)
    For ix=1 To _Screen.FormCount
        If _Screen.Forms(m.ix).Name==formun_adi
            Return m.ix
        Endif
    Next
    Return 0
Endfunc



** Asıl problem farklı bir formun private datasession'ı aktif iken
farklı bir sessiondaki hali hazırda açık olup bekleyen bir table'dfan bilgi almak, insert etmek yada update etmek...
Bunları yaparken kendi formundaki combo, grid v.s. dataları uçurmadan...
Çünkü güncellenecek bilgi o an için formda oluşan nihai data...?

5

Re: Private datasession - form object ilişkisi

radiokaos yazdı:


** Asıl problem farklı bir formun private datasession'ı aktif iken
farklı bir sessiondaki hali hazırda açık olup bekleyen bir table'dfan bilgi almak, insert etmek yada update etmek...
Bunları yaparken kendi formundaki combo, grid v.s. dataları uçurmadan...
Çünkü güncellenecek bilgi o an için formda oluşan nihai data...?

o zaman private data session olan boş bir form yaparsın. bu formdan o boş formu çağırırsın. boş formun girişinde this.datasessionid=xdatasesid dersin. xdatasesid dediğimiz de içinde tablolara erişmek istediğin form olur. işini init içinde bitirir ve return .f. ile dönersin.

Haksızlıklar karşısında susanlar, dilsiz şeytanlardır!
www.metinemre.com

6

Re: Private datasession - form object ilişkisi

Mantıklı gibi geliyor ama diyelim ki mevcut aktif olan formda bir grid var,
bu griddeki x sayıdaki kaydı diğer (bundan önce açılmış olan herhangi bir) sessiondaki cursor/table insert edeceğim.

sizin dediğiniz gibi bir for-next döngüsü ile her kayıt verisini parametrik olarak o session'u kullanan boş forma gönderip orada işlem yaptırmak
yada
grid table select ile array'a atıp o formun içerisinde for next ile kursore atmak....

az daha tırmalamak gerekecek...

Son durum da datasessionlar arasında table/cursor taşımak yada ilişkilendirmek gibi birşey çıkıyor?

7

Re: Private datasession - form object ilişkisi

Zaten bu olay vfp10 wish listinde geçiyormuş....

VFP Version 10 Wish List - Visual FoxPro Wiki
6 Jun 2008 ... How do I get a cursor from one data session to another quick and easy? .... data items on the fly, and to which you can easily attach a ...
fox.wikis.com/wc.dll?Wiki~VFPVersion10WishList - Cached - Similar

8

Re: Private datasession - form object ilişkisi

Version 10 olmadigina gore unut gitsin:) Ben olayi anlamakta gucluk cekiyorum ve sanirim bir hata var bu iste.

Visual Fox Pro
For ix=1 To _Screen.FormCount 

        If _Screen.Forms(m.ix).Name==formun_adi
            Return m.ix
        Endif
    Next

ile hallettim demissin ama bunun nasil ise yaradigini biri bana anlatsin:) Form.Name bir cesit nesne adi. Benim ayni anda 100 tane formum olabilir o sirada ekranda gorunen (tamam abarttim 5 olsun) ve hepsinin de adi "Form1" olabilir. Ki benim formlarimda genelde oyledir. Ustelik form.name herhangi bir zamanda degistirilebilen birsey. Uzun lafin kisasi sana aradigin formu verebilmesi icin kendini cok kisitlayan bir uygulama yazma tarzin olmasi gerekir (tum formlarda ozenle name propertysini essiz yapmak vs)

Datasession'lar arasi data aktarimi basit, XML, array, tablo kullan, hatta duz metin bile olur. Benim basit bir dataset classim var bunu yapmak icin:

Visual Fox Pro
** Dataset class to pack given cursors into an object to pass between data sessions

Define Class DataSet As Custom
    TableCount = 0
    DataSessionId = 0
    Dimension TableInfo[1]
 
    Procedure Init
        This.DataSessionId = Set("Datasession")
    Endproc
 
    Procedure AddTable(tcAlias, tcAsAlias)
        Local Array aStruc[1],aStripped[1]
        LOCAL ix
        Afields(aStruc,m.tcAlias)
        Dimension aStripped[ALEN(aStruc,1),5]
        For ix = 1 To Alen(aStruc,1)
            aStripped[m.ix,1] = aStruc[m.ix,1]
            aStripped[m.ix,2] = aStruc[m.ix,2]
            aStripped[m.ix,3] = IIF(aStruc[m.ix,2]='V',MIN(aStruc[m.ix,3],254),aStruc[m.ix,3])
            aStripped[m.ix,4] = aStruc[m.ix,4]
            aStripped[m.ix,5] = aStruc[m.ix,5]
        ENDFOR
 
        This.TableCount = This.TableCount + 1
        Dimension This.TableInfo[this.TableCount]
        This.TableInfo[this.TableCount] = Createobject('Custom')
        With This.TableInfo[this.TableCount]
            .AddProperty('aStructure[1]')
            .AddProperty('aRecords[1]')
            .AddProperty('Records')
            .AddProperty('Alias',m.tcAlias)
            .AddProperty('AsAlias', Iif(Empty(m.tcAsAlias),m.tcAlias,m.tcAsAlias) )
 
            Acopy(aStripped, .aStructure)
            Select * From (m.tcAlias) Where !Deleted() Into Cursor __crsTemp__ nofilter
            .RecordS = Reccount()
            If .RecordS > 0
                Dimension .aRecords[RECCOUNT()]
                Scan
                    Scatter Name .aRecords[RECNO()] Memo
                Endscan
            Endif
            Use In '__crsTemp__'
        Endwith
    Endproc
 
    Procedure RestoreDataSet(tnDataSessionID,tlRestoreIfNotUsed) && restore all with saved aliases
        Local lnCurrentSession,ix
        lnCurrentSession = Set("Datasession")
        For ix = 1 To This.TableCount
            This.Obj2Cursor( This.TableInfo[m.ix].Alias, '', m.tnDataSessionID,m.tlRestoreIfNotUsed )
        Endfor
        Set DataSession To m.lnCurrentSession
    Endproc
 
    Procedure Obj2Cursor( tcStoredAlias, tcAlias, tnDataSessionID,tlRestoreIfNotUsed )
        Local ix,jx
        If !Empty(m.tnDataSessionID)
            Set DataSession To m.tnDataSessionID
        Endif
        For ix = 1 To This.TableCount
            With This.TableInfo[m.ix]
                If Upper(.Alias) == Upper(m.tcStoredAlias)
                    tcAlias = Iif(Empty(m.tcAlias), .AsAlias, m.tcAlias )
                    If (m.tlRestoreIfNotUsed And Used(m.tcAlias))
                        Select (m.tcAlias)
                    Else
                        ** Check array for any c(255)
                        Local lnArrElem
                        For lnArrElem=1 To Alen(.aStructure,1)
                            If .aStructure[m.lnArrElem,3] = 255 And .aStructure[m.lnArrElem,2]='C'
                                .aStructure[m.lnArrElem,3] = 254
                            Endif
                        Endfor
                        Create Cursor (m.tcAlias) From Array .aStructure
                        For jx = 1 To .RecordS
                            Append Blank
                            Gather Name .aRecords[m.jx] Memo
                        Endfor
                        EXIT
                    Endif
                Endif
            Endwith
        Endfor
        Set DataSession To This.DataSessionId
    Endproc
Enddefine


Bu array kullaniyor. Mesela:

Visual Fox Pro
Select * from ;

    (_samples+'data\customer') ;
    where country = 'USA' ;
    into CURSOR xx nofilter
 
local oDataSetPacker as 'DataSet' of 'd:\vfpcommonclasses\dataset.prg'
oDataSetPacker = newobject('DataSet','d:\vfpcommonclasses\dataset.prg')
 
oDataSetPacker.AddTable('xx','BenimMusteriler')
MESSAGEBOX(TEXTMERGE('Datasession id: <<SET("Datasession")>>'))
CLOSE DATABASES ALL && gereksiz - sadece ornek icin, ortada acik tablo yok
 
loSession = CREATEOBJECT("ornek",m.oDataSetPacker)
loSession.Test()
 
DEFINE CLASS ornek as Session
    Datasession = 2 && private
 
    PROCEDURE Init(toDataSet)
    toDataSet.RestoreDataSet(this.DataSessionId,.T.)
    ENDPROC
 
    PROCEDURE Test
        MESSAGEBOX(TEXTMERGE('Datasession id: <<SET("Datasession")>>'))
        SELECT * FROM (_samples+'data\orders') ;
        INNER JOIN BenimMusteriler ON BenimMusteriler.Cust_id = Orders.Cust_id ;
        INTO CURSOR crsTest
        BROWSE
    endproc
enddefine

9

Re: Private datasession - form object ilişkisi

Sevgili Çetin üstadım,

Ellerine sağlık. Çok teşekkür ederim.

Benim amacım girişte yalnızca bir kez çalışan Main_Menu isimli formdan bir kaç veri alarak diğer child formlarda kullanmaktı.
Yani ismi cismi belli olan ve sadece tek olan bir form.
bilgi olarak tarih alanı onlardan sadece bir tanesi... (user_name, user_no, firma ismi, çalışılan sezon v.s. .... gibi
bir çok veri ilk Main_menu formunda olgunlaşıyor)
ve bunları diğer her child programında remote sql database'den okutup performans kaybı yaşamamak için küçük bir çözüm...
Umarım foxcu arkadaşlara yanlış bilgilendirme yapmamışımdır...

Ama işin nitelikli bir çözüm olması konusunda sonsuz haklısınız.
Form propertylerinden olsa gerek herhalde private'e geçince form.name object'lerine bir şekilde ulaşamaz oldum.

Ama dataset class'lar için çok teşekkür ederim. Gece mesaisinde onları kullanacağım. Ufkunuz sayesinde gerisi çorap söküğü gibi gelecek..

Ufak tefek sorularımla yine siz üstadları rahatsız edeceğim.
Verdiğiniz cevaplar ve zamanınız için tekrar teşekkür ederim.

Fox'la kalın...

10 Son düzenleyen, ugurlu2001 (13.07.2010 08:48:06)

Re: Private datasession - form object ilişkisi

Radiokaos; ( ismini bilmediğim için nickin ile hitab ediyorum )

Bahsettiğin konu için biraz daha farklı bir çözüm düşünsen! Şöyle ki:

1) Programımnın başlandığında bir Public class tanımla. Mesela adı "ogMyPub" olsun.
2) Bu public class için projenin her yerinde kullanacağın, sana her zaman, her yerde gerekli olacak property ve method ları tanımla.
3) Gerektiği yerde kullan.

Projenin ilk başında biraz uğraştırıcı hatta angarya olabilir. Ama nimetlerinden faydalandıkça bu konu için özellikle "mutlaka yapılması gerekiyor" diyen usta / üstat lara hakverirsin. En azından ben kendi adıma "Kesinlikle haklılarmış". dedim. ( Çetin üstat bu kısmı sana göndermeydi ) smile

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü