PB詳細學習筆記_第1頁
PB詳細學習筆記_第2頁
PB詳細學習筆記_第3頁
PB詳細學習筆記_第4頁
PB詳細學習筆記_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

當我們在程序中用修改數(shù)據(jù)庫的時候,只要不用commit切程序在運行,我們此時是查看不到數(shù)據(jù)庫中當前操作的數(shù)據(jù)的,只有commit后,或退出該程序時,才能在數(shù)據(jù)庫中查看到修改后的數(shù)據(jù)。這是因為修改數(shù)據(jù)的時候是先有一個緩沖區(qū),此時還沒有修改到實際的數(shù)據(jù),多以此時沒用commit,而用rollback的時候,對緩沖區(qū)的修改代碼將不被執(zhí)行;此時就是起到出錯數(shù)據(jù)回滾的操作但是,當我們修改了數(shù)據(jù)沒用到commit的時候,而是直接退出程序,此時數(shù)據(jù)庫緩沖區(qū)中的修改代碼也會被執(zhí)行,也就是說,只要不用rollback,推車程序時數(shù)據(jù)也會被更改。所以,當我們某個地方會出錯需要數(shù)據(jù)回滾時,就要在那里進行rollback操作。在數(shù)據(jù)窗口對象里設置顯示值和實際值時,要注意:當輸出文檔時任然使用的是實際值,顯示值值是看的,沒有實際意義。在我們第一次裝PDM時,裝數(shù)據(jù)庫的時候數(shù)據(jù)庫是沒有程序的內(nèi)部用戶的,所以一般是建一個空數(shù)據(jù)庫,然后進行初始化,這樣數(shù)據(jù)庫就有了2個用戶了,然后再將有數(shù)據(jù)的數(shù)據(jù)庫還原上去,但此時該數(shù)據(jù)庫也是沒有用戶的,就要給它授權,即映射,此時執(zhí)行Grant的代碼就是映射授權。所以,當沒有系統(tǒng)用戶時,執(zhí)行Grant是沒有用的。我們在pb中,事件是可以繼承的,方法是不能繼承的:如果子對象中的該方法寫了新代碼,則調(diào)用時是執(zhí)行新寫的代碼,如果子對象該方法中什么也沒寫,則會調(diào)用父對象的該方法所以,可見繼承是可以先執(zhí)行父的再執(zhí)行子的,方法是不行的這個就叫做多態(tài)1.因為標題名字是字段名字加_t,所以,在自定義字段時,設置字段名時不要有“_”.一定要注意補丁包升級和數(shù)據(jù)庫升級,補丁包升級是將我們的程序進行升級,而數(shù)據(jù)庫升級是對數(shù)據(jù)庫進行修改操作的升級。二者不是一回事,都要進行操作。我們要區(qū)分數(shù)據(jù)庫版本和程序版本,兩者要對應才能正常運行。我們調(diào)試時用的動態(tài)庫為PB文件夾下的動態(tài)庫,程序運行時用的是Bin目錄下的動態(tài)庫,程序安裝時用的也是Bin目錄下的動態(tài)庫,所以要清楚不同環(huán)境下的運行要求。修改數(shù)據(jù)窗口對象的查詢語句時,先剪切再添加,這樣更能反映到當前PB中來。在我們觸發(fā)事件打開窗口的時候,一定要注意打開窗口和當前窗口的關系,如果他們是繼承關系,則會報錯的~!在寫SQL語句時注意where1=1的用法,我們開始就把這個寫在一個變量中,當要增加條件時就直接加在后面。從而不用擔心where出現(xiàn)的位置問題。在PB寫代碼時,不同的目標可以引用對方的庫,所以我們編譯時,先編譯功能小的庫,再編譯功能齊全的庫。為什么呢? 比如:我們目標1調(diào)用目標2的庫1,在庫1中調(diào)用了許多目標1中的其他庫的對象,在編譯時就會將這些聯(lián)系都寫在庫1.pbd文件中,當編譯目標2時也會重新生成庫1.pbd,由于在目標2中沒有庫1中調(diào)用其他庫的對象,因為目標2只是用到了庫1中很小的一部分對象,這時編譯并不會報錯,所以重新生成的.pbd文件是不全的(一般發(fā)生在多個程序集成在一起的情況)。所以,我們只能先編譯功能小的目標,再編譯功能大的目標。防止相同庫先后編譯發(fā)生覆蓋的錯誤。記住,在分析代碼的時候,要分功能模塊來看,不要整體的來分析,那樣會很復雜而且不容易想清楚,很容易亂。分析每一小塊的代碼,知道他的作用和關聯(lián);最后將每個塊聯(lián)系起來串一邊,就能曉得當前腳本的功能了。有時候不一定要分析某個函數(shù)它內(nèi)部是怎么操作的,只需要曉得它的返回結果,這樣的函數(shù)就不用費勁的去分析代碼了。在我們的程序中是有版本的,當定義好了程序中的版本后,就要進行數(shù)據(jù)庫升級,這個升級就會將版本信息存放到數(shù)據(jù)庫中,只有程序的版本和數(shù)據(jù)庫的版本一致時,才可以登錄系統(tǒng)。PB寫的代碼調(diào)試是要依賴與環(huán)境的,所以,當調(diào)試出問題時,就要把一些支持調(diào)試的.DLL文件拷貝到PB的安裝目錄下面去。注意考入的.dll文件要和當前版本的程序相匹配,因為不同版本的程序里的.DLL文件是不一樣的。要注意區(qū)分程序運行的代碼和程序安裝的代碼,兩者是有區(qū)別的。我們要注意本地數(shù)據(jù)源的連接,不是創(chuàng)建了數(shù)據(jù)源就可以能連的上去,同時也要為數(shù)據(jù)源指定數(shù)據(jù)庫文件。否則找不到數(shù)據(jù)。我們在使用對象的各種類型變量時,一定要注意值的滯留問題,如有這種情況,則要在開頭或結尾將其進行清空。Eg:當有一個數(shù)組il_partid[]時,開始我們循環(huán)找到了2個值,放在il_partid[1],il_partid[2]里面,完成了滿足條件的查詢。但是當我們下一次檢索時,只找到一個滿足條件的值,放在了il_partid[1]里,此時我們查詢時,則會出錯,出現(xiàn)2個滿足條件的值,因為我們值改變了il_partid[1],但是il_partid[2]上次查詢結果的值仍然保留在,故會出錯。所以,我們在每次執(zhí)行代碼前就要清空:il_partid[]=ll_empt[]這樣就避免了出錯。我們要清楚事件的觸發(fā)和函數(shù)的調(diào)用,當我們不好用某個動作來觸發(fā)某個自定義的事件代碼時,我們可以將該事件放在另一個事件的結尾用trigger或post來觸發(fā)自定義事件。事件其實就是代碼~!注意:在我們用if判斷的時候,如果用=是表示判斷,不是賦值,而用函數(shù)返回值判斷時,是要執(zhí)行該函數(shù)再判斷的,所以,不要搞混了,要清楚什么時候執(zhí)行,什么時候表示判斷。Modify基本可以修改數(shù)據(jù)窗口中所有的屬性項。我們要修改某對象的源時,可以將其Export導出源碼,然后我們就雜源碼的定義部分修改對象的屬性。要知道,我們對源直接修改就是修改對象的本身屬性。any要想知道Any類型變量中保存數(shù)據(jù)的類型,可以使用函數(shù)ClassName()我們要連接多個數(shù)據(jù)庫時,第一個數(shù)據(jù)庫算是默認的,所以在我們用游標或select語句時都不用usingsqlca;不用就算是默認的。所以,當用多個數(shù)據(jù)庫時,檢索數(shù)據(jù)的時候就要在查詢的地方放用using語句,不然它算是連接到了默認的數(shù)據(jù)庫,則會出錯。不管用哪個數(shù)據(jù)庫都是要定義好數(shù)據(jù)源的,同時在代碼中聲明連接,這樣才能得到數(shù)據(jù)。(聲明:sqlca.odbc=;sqlca.code;……)在應用對象中聲明的是數(shù)據(jù)源參數(shù)的鏈接,因為數(shù)據(jù)源和數(shù)據(jù)庫之間的關系在創(chuàng)建數(shù)據(jù)源的時候一般會定義好的。所以鏈接數(shù)據(jù)庫,可看做2個部分,一個是創(chuàng)建數(shù)據(jù)源,再個是鏈接數(shù)據(jù)源。我們用自定義的數(shù)據(jù)窗口對象時,選擇的是外部數(shù)據(jù)源,此時在畫板界面上,是先定義字段的屬性,再增加字段的。要分清PB中對象和類的區(qū)別:一般我們將window menu treeviewitem等就是“類”,專門作為一種數(shù)據(jù)類型來定義該類型的實例。而我們繼承是在原類的基礎上創(chuàng)建一個新類。New是創(chuàng)建新對象,不同與繼承。我們的PDM的代碼包CODE一般包含2個文件夾:Inte_pbr文件夾:里面存放的是程序運行時需要的所有圖片,但是加載圖片進去還不夠,它里面還有一個配置文件(INTEMAN.PBR;INTEPDM.PBR等),將每個圖片的路徑信息都寫在了里面,只有這樣程序才能完全找到使用。這個文件夾要安裝到C盤下面,這是程序指定的路徑。因為在代碼中的編譯對象中包含了這2個文件夾的路徑,所以當編譯完成后生成的.pbd文件就包含了2部分的內(nèi)容。當沒編譯只是運行代碼時,這個包就要放在指定路徑下了,不然運行時圖片都不會顯示出來。另外一個就是我們代碼的安裝包了。當你創(chuàng)建一個工作目標(.pbt)后,它會自動創(chuàng)建一個應用庫(.pbl),我們創(chuàng)建和操作的對象就放在這個應用庫下面。層次結構:—工作空間—目標 —應用庫(多個) —對象(多個)—目標(多個)一般一個工作目標就是一個應用程序,就是說同一個目標下不同應用庫中的對象是可以互相訪問的。同一目標下的不同庫中的對象可以相同。不管是同一目標還是不同目標或是不同的庫中,我們都可以將有用的對象拷貝到指定的庫中。且一個工作目標里面只有一個應用庫中有且只能有一個(應用對象)。我們創(chuàng)建的全局變量,它是在整個目標(程序)中是有效的。應用對象的屬性一般具有全局性,所以要慎重設置。我們在PB系統(tǒng)樹中創(chuàng)建的對象可以看做是一個實例對象,直接拿出去用,也可以看做一個類,用它來創(chuàng)建新的對象,新的對象將有原對象的所有屬性和事件、方法。不同對象中的控件名可以相同,不同庫中的對象名字可以相同,不同目標的庫名也是可以相同的。但是,在一個目標中,不要將庫名中的對象名取一樣的,這樣會出錯,因為同一目標下的對象是可以相互訪問的。在應用對象中設置事務對象的連接屬性,與在DBprifile中添加DB是沒有關聯(lián)的。當Return屬于某個腳本時,就退出該腳本的運行,當它是某個腳本函數(shù)的代碼時,則返回到調(diào)用該函數(shù)的位置。我們要清楚每個函數(shù)在各種情況下的用法。它是與控件連一起用的還是單獨可以用的,最好根據(jù)函數(shù)的功能和意思來分辨。我們要把形參當作實際的值來看待。一定要注意每個函數(shù)的功能,以及他們之間的內(nèi)在聯(lián)系:例如:getfilesavename()它是打開一個準備要保存的文件路徑對話框,它返回路徑名和文件名,除此之外不做其他的操作。又如oleobject的saveas():它是將文件保存到一個指定路徑,當這個路徑和getfilename()的路徑不相符時或沒有傳遞時,它就會報錯而不能保存。又如PB中的saveas()它不關前面的getfilesavename(),它的功能就是打開保存對話框,保存到指定位置進行保存。我們所用的對象其實就是一堆視圖化的代碼,當我們想要改變某個對象的屬性或內(nèi)容時,可以直接編輯他們的源代碼:Editsource.當我們在定義函數(shù)時,規(guī)定了返回類型,則它會要求你返回一種類型。 所以,如果不想返回值,則在定義的時候在返回值上填(none)我們用戶定義事件其實分2種情況:通過事件ID調(diào)用windows已經(jīng)存在的事件。此時各項參數(shù)都是設置好的,只需要設置名字。將事件ID設置為(none),此時我們就可以自己設置事件的各項參數(shù)了,此時可以說才是真正的用戶事件。在pb中觸發(fā)事件有2種方法:通過我們手動的操作,來觸發(fā)相應的事件。通過TriggerEvent()或者Postevent()來觸發(fā)。Object.TriggerEvent(clicked!)是立即觸發(fā)用戶指定的事件,在繼續(xù)調(diào)用下面的事件,屬于同步調(diào)用。Object.Postevent(clicked!)是將用戶指定的事件放置到指定控件事件隊伍中的末尾,等所有的事件都完畢后再執(zhí)行該指定事件,屬于異步調(diào)用事件。Object.triggerevent(‘ue_delete’) 當執(zhí)行的是用戶自定義的事件時,則要加上引號,而不是以感嘆號結尾。dw_department.eventtriggerue_delete()w_main_frame.eventpostue_paint()這是CB控件clicked事件的一段腳本。可見,ue_delete()是dw_department對象的事件,現(xiàn)在是放在CB的clicked事件中去觸發(fā)dw_department對象的ue_delete()事件??梢姡录菍儆趯ο蟮?,所以前面要加限制。他們通過ODBC連接的數(shù)據(jù)源時,在PB中是通過事務對象連接的ODBC的數(shù)據(jù)源,而在我們配置數(shù)據(jù)源時就定義好了要連接的數(shù)據(jù)庫。我們在PB中對數(shù)據(jù)進行的修改操作基本都是對緩沖區(qū)進行的。我們要區(qū)別緩沖區(qū)的數(shù)據(jù)和數(shù)據(jù)窗口顯示的數(shù)據(jù),大多情況緩沖區(qū)會直接反應到數(shù)據(jù)窗口上,但要注意區(qū)分開來。在pb中建的DBfile文件數(shù)據(jù)庫,并不是使我們開發(fā)的應用與數(shù)據(jù)源連接,但是它將數(shù)據(jù)庫直接反應到PB中來了,我們可以直接在這里對數(shù)據(jù)庫進行操作,而不用跑去修改本身的數(shù)據(jù)庫。記住,我們用事務對象連接的是數(shù)據(jù)源,DBfile是數(shù)據(jù)庫的顯示。所以,我們通過對DBfile的修改來直接對數(shù)據(jù)庫進行修改。我們連接一個DBfile只是可以對其進行操作,同時也必須要連,因為我們處理數(shù)據(jù)時要進行語法效驗,如果不連的話在保存時會報錯。因為在我們沒有運行代碼時,代碼中連接數(shù)據(jù)庫的代碼根本就沒有執(zhí)行,故沒有連到數(shù)據(jù)庫中,所以,進行語法效驗時是根據(jù)DBfile中連接的數(shù)據(jù)庫進行效驗的。所以,以后每次都要連上DBfile文件。我們創(chuàng)建數(shù)據(jù)窗口對象時,會有標題名和內(nèi)容名,內(nèi)容名就是我們數(shù)據(jù)庫表的字段名字,而標題名一般是表的字段名字加上“_t”,,但是這是對象的名字,我們還要給標題的每個對象設置文本內(nèi)容。別把對象的名字和存在的內(nèi)容搞混了~~~!用游標讀取數(shù)據(jù)時,讀取一行就要用sqlcode進行檢查一邊:當為0時,這成功讀取了當前的一條數(shù)據(jù)當為-1時,讀取錯誤當為100時,則表示都讀取完了當使用游標和存儲過程時,十分注意commit和rollback的使用,因為他們將關閉兩者的使用。只要是對象,一般都是可以繼承的。菜單的工具欄只能顯示在MDI窗口中。我們的全路徑是目錄\文件名。所以目錄是沒有“\”的。fileopen()以指定的方式打開指定的(存在或不存在)文件,可讀或可寫返回句柄Fileopen(filepath,streammode!,write!,lockwrite!,replace!)此時表示,如果該路徑文件已經(jīng)存在,那么就覆蓋該文件。此時一定要注意:當是以寫的方式打開(write!)時,它一定會重新創(chuàng)建一個空文件,如果路徑已經(jīng)存在,且有replace!,那么該空文件就會覆蓋指定文件。如果路徑不存在,那么就會創(chuàng)建新的指定空文件。當是以讀的方式打開時,它不會創(chuàng)建新的文件,而是讓你指定要打開的文件。當lockwrite!時,你可以看該文件當lockread!時,你就不能看該文件了OleObjectWord=CreateOLEObjectli_Ret=OleObjectWord.ConnectToObject("","word.application")IFli_Ret<>0THENli_Ret=OleObjectWord.ConnectToNewObject("word.application")//沒有打開則新建 ifli_Ret<>0then MessageBox('OLE錯誤','OLE無法連接,錯誤ID:'+string(li_Ret)+'可能是Word安裝不正確!') endifendifOleObjectWord.Documents.Add()此時,上面值是連接了操作的對象。只有當OleObjectWord.Documents.Add()時才會打開一個新的文件。此時它就會成為當前活動對象。OleObjectWord.ConnectToObject("實例路徑","指定的服務器應用程序")也就是說:實例路徑,就是你要操作的文件全路徑服務器應用程序,就是支持文件的應用程序。當我們沒有實例路徑時,它會對當前活動對象進行操作當有實例路徑時,它就對指定路徑的文件進行操作。OleObjectWord.ConnectTonewObject("指定的服務器應用程序")創(chuàng)建新的對象并連接到該對象上。此時就要注意了,它創(chuàng)建的應用對象是空的,也就是說它里面連空白都沒有。此時就要用OleObjectWord.Documents.Add()來增加操作空間。Saveas()既可用OLE對象,也可用于數(shù)據(jù)窗口對象2者的用法不一樣,具體情況具體分析。用于數(shù)據(jù)窗口對象時,可以保存數(shù)據(jù)也可以保存統(tǒng)計圖。我們可以直接給一個表的字段定義主鍵,但是給表定義外鍵時,同時也要指出是對應的哪個表的主鍵。先找主鍵,在去聯(lián)系它的外鍵。我們在調(diào)用外部函數(shù)前對其聲明時,記住:一個聲明要寫成一行。functionintFileExpand(stringInputFile,stringOutputFile)library"intedll.dll"(一行)subroutineFillMany(intserial_no,refstringpassword)library"intedll.dll"(一行)我們的事件一般都是定義好的,當觸發(fā)該事件的時候,就執(zhí)行該事件中的腳本,我們是在腳本中寫代碼,調(diào)用函數(shù)。當是繼承對象后,它里面的事件和函數(shù)都會繼承過去,且不可修改,當繼續(xù)加代碼時,它會先執(zhí)行原有的代碼,再執(zhí)行新寫的代碼。if keydown(keyenter!)then ifthis.text="" then return else uo_ok.setfocus() uo_ok.triggerevent(clicked!) endifendif可見,觸發(fā)的按鍵以!來區(qū)分要出發(fā)事件時,也是用事件名+!響應式窗口一般是提示且必須執(zhí)行完才會繼續(xù)執(zhí)行的窗口,所以,當它的事件執(zhí)行完時,我們在代碼結尾用close()來關掉它。要知道各種值的保存時間:實例變量:當實例對象關閉時,變量下次重置全局變量:當程序結束下次再開時重置。注意事件的觸發(fā)條件,如果不滿足就給它加代碼加以限制。ifisnull(ls_newcode)ortrim(ls_newcode)=''ortrim(lower(ls_newcode))='null'thenls_newcode=''注意判斷為空的幾種情況。Null要加引號用。注意用戶對象的使用:例如標準可視用戶對象,它其實就是一個控件,但是我們使用它的時候它會在窗口界面創(chuàng)建屬于該對象的控件,而不是對象本身。所以,千萬注意對象名和你創(chuàng)建的對象控件名字。要理解這樣就可以重復使用了。注意可視對象和不可視對象引用的方法:getitemstring()、getitemnumber()它是得到數(shù)據(jù)窗口中(主緩沖區(qū))某項的數(shù)據(jù),注意類型Setitem()它是給數(shù)據(jù)窗口中(主緩沖區(qū))的某項賦值,針對的是緩沖區(qū)的。類型為Any類型。Settext()它是給浮動數(shù)據(jù)窗口賦值,而不反應到緩沖區(qū)里。其值要與所在列類型相兼容。當用setitem()賦值后,要反應到浮動數(shù)據(jù)窗口中,這要移動焦點或在代碼中調(diào)用Accepttext()函數(shù)。Accepttext()是將漂浮在數(shù)據(jù)窗口中的內(nèi)容放到緩沖區(qū)里去。(必須通過有效驗證。)注意它的用法,當焦點從漂浮數(shù)據(jù)窗口中的一項移到另一項時,系統(tǒng)自動會將漂浮狀態(tài)的數(shù)據(jù)反應到緩沖區(qū)。但是,當焦點從當前漂浮數(shù)據(jù)窗口移到其他控件時,則漂浮數(shù)據(jù)是不會反應到緩沖區(qū)的,所以,我們一般在數(shù)據(jù)窗口的Losefocus()事件中用到此函數(shù)。記住:設置焦點一般是以對象為單位的。不要在Itemchanged或ItemErrorevent中編寫Acceptext()函數(shù),因為Acceptext()函數(shù)有可能驅(qū)動ItemChanged或ItemErrorevent,這將造成死循環(huán)的出現(xiàn).

GetText():讀取編輯控件的文字.String(date,{fomate})將數(shù)據(jù)以指定格式轉換成字符串。String(ll_id,’00’) Ifll_id=1, returnll_id 則ll_id=01insertrow()dw_1.insertrow(0)它是在最后一行后再插入一行。dw_1.insertrow(row)是插入到第row行,就是在第row行前面再插入一行,也就變成了第row行了。返回值是行號。注意對象的繼承層次:當dw_2繼承dw_1后,就有了它的所有事件和屬性,而且,我們可以對dw_2中的事件和屬性繼續(xù)修改。當dw_3繼承了dw_2后,dw_3就有了dw_2和dw_1所有的事件和屬性,此時用到dw_3時就會出現(xiàn)層次性,看見不同層次時的對象代碼。我們創(chuàng)建了的用戶對象,將它丟到窗口中用時,其實就是一種繼承,繼承過來的對象就有原對象的所有事件和屬性。繼承后的對象就是一個新的對象了。數(shù)據(jù)窗口對象類型:Grid時,它的列排列順序是不能改的。environmentle_env 環(huán)境對象getentironment(le_env) 用這個函數(shù),應用程序能夠得到當前運行的操作系統(tǒng)、使用的CPU類型、操作系統(tǒng)的版本、屏幕的大小和顏色數(shù)等信息。 成功返回1.profilestring(文件名(包含路徑),section,key,default)section:指定要得到值所在的節(jié)。key:指定要得到值的名稱(理解值的名稱,其實就是包含某個值的變量名)default:指定的文件、節(jié)名、項目不存在時,函數(shù)返回該參數(shù)指定的值。成功返回指定的key值,錯誤返回default的默認值。就是:文件名,節(jié)名,值名,默認值grouser=createu_userifNotIsValid(guo_user)then haltclose returnendif可見,我們在創(chuàng)建用戶對象時,最好是判斷它是否創(chuàng)建成功,很容易找到錯誤。getapplication()得到當前應用對象的句柄,通過句柄來查詢或修改應用對象的屬性。Applicationapp先定義一個應用的變量App=getapplication()App.toolbartips=false 也可以直接:getapplication.toolbartips=false可知,應用對象中修改工具欄屬性和修改字體屬性可以影響到全局窗口風格。this.hide()iuo_timer=createu_timerguo_ge.uf_get_toolbar_profile("w_main_frame",this)PostEvent("ue_open")注意這段代碼,這的窗口w_main_frame中open()事件的一段腳本。其中,this就是代表了窗口w_main_frame,但是一定要注意參數(shù)傳遞的數(shù)據(jù)類型,同時也要注意引號的恰當使用:(“”)。W_main_frame本身代表了窗口,但是給它加上引號后,那么它傳遞的就不是一個窗口數(shù)據(jù)類型了,我們知道窗口本身就是一種數(shù)據(jù)類型,而不是一個字符串。只有this傳遞的才是一個窗口。所以,一定要注意參數(shù)的類型和引號的使用。以及它本身代表了什么意思。如:as_window_name=”w_main_frame”我們可以this.text=’1’也可以w_main_frame.text=’1’但就是不能as_window_name.text=’1’因為as_window_name它是一個字符串類型,而不是對象類型。所以,在使用數(shù)據(jù)或類型時,一定要注意類型的匹配。Datawindowchild是子數(shù)據(jù)窗口對象,也是一種數(shù)據(jù)類型。opensheetwithparm(對象1,string,對象2,位置,放置方式)對象1:要打開工作表的窗口對象。Eg:w_main_child沒有引號String:不定,會將這個值保存到消息對象的Message.stringparm中。對象2:主窗口位置:就是將打開工作表的標題放到倒數(shù)第二個菜單中,作為選項。放置方式:打開工作表放置主窗口的位置。傳遞的數(shù)據(jù)就只有3類型:數(shù)值類型 Message.DoubleParmPowerObject(比如結構)Message.PowerObjectParm字符串類型 Message.StringParm傳遞的參數(shù)就保存在Message的這3個屬性中,在子窗口中就可以將傳遞過來的數(shù)據(jù)保存下來。當我們定義函數(shù)時,在選擇傳遞參數(shù)的類型時,注意傳遞參數(shù)的返回值,當是值傳遞時,他們是互不影響的。當是reference時,則表示是地址傳遞,他們的值是相互影響的。他們的變量名不一樣,但是他們的值是一樣的。且相互影響。注意:我們在代碼中用到的字段名子,是數(shù)據(jù)窗口對象內(nèi)容的標題名字,而不是標題的名字,更不是標題內(nèi)容的名字。動態(tài)SQL語句:ls_sqlsyn_id="selectpv_objidfromdm_psetvalue_"+string(ll_psetid)+& "wherepv_codelike"+trim(ls_cucode)+"AND"+"(pv_objid<>"+string(ll_partid)+")"PREPARESQLSAFROM:ls_sqlsyn_id;DECLARElcr_cur_id DYNAMICCURSORFORSQLSA;OPENDYNAMIClcr_cur_id USINGDESCRIPTORSQLSA;dowhiletruefetchlcr_cur_idINTO:ll_partid; ifsqlca.sqlcode=0then ll_cnt_id++ ll_id[ll_cnt_id]=ll_partid elseifsqlca.sqlcode=100then exit else guo_ge.uf_warn_db_error() closelcr_cur_id; return endifloopcloselcr_cur_id;一定要注意類型,當是string時則拿出來直接寫,當不是string時,則強制轉換后拿出來直接寫。我們定義的用戶對象可以包含屬性,事件,函數(shù):用戶對象的屬性,其實就是它定義的實例變量。我們不用返回數(shù)據(jù)closewithreturn()函數(shù),它會出現(xiàn)不可知的問題,我們一般在它的某個事件中用Close()將它關閉,同時在的close()事件中用:Message.powerobjectparm=powerobject來傳出數(shù)據(jù)。同時一般將數(shù)據(jù)類型定義成實例類型,這樣就可以在不同對象中使用了。我們用openwithparm()函數(shù)時,一定要注意打開窗口的類型,當打開的是response!相應式窗口時,則它一定會執(zhí)行完openwithparm()函數(shù)的所有事件和代碼才會繼續(xù)執(zhí)行下去。而打開的窗口是其他類型的窗口時,則會在打開窗口的同時喜劇執(zhí)行下面的代碼,所以要注意窗口的類型和代碼執(zhí)行的時間。在我們腳本中定義數(shù)組的時候,不要將同類型的數(shù)組名和變量名寫成相同的。我們用distinct時,一般只對查詢的第一字段使用,其他的都不需要。"selectdistinctcode,name,partidfromtb_gygck"+& "wherecodelike"+"~'%"+ls_code_name+"%~'ornamelike"+"~'%"+ls_code_name+"%~'"我們一定注意值為空(null)的情況,當一個null值的變量取判斷條件是否成立時,它都會滿足條件的。:Setnull(code) code>0或者code<0都會判斷其成立的。對于新的數(shù)據(jù)窗口,開始時是沒有行的,你要用:fori=1toll_total ll_row=dw_data.insertrow(0) dw_data.setitem(ll_row,'partid',al_partid) dw_data.setitem(ll_row,'ord',ll_ord[i])所以,要用插入一行來賦值。當我們在做查詢窗口數(shù)據(jù)的時候,一定要在可以多次查詢控件的前面加上datawindow.reset()。因為,如果數(shù)據(jù)不清掉,在多次查詢的時候會產(chǎn)生數(shù)據(jù)的疊加。我們一定要注意“樹控件”,我們加載了一個樹控件后,里面是什么都沒有的,此時我們就要建treeviewitem定義樹視圖節(jié)點,然后在將該節(jié)點加載到樹控件中,這樣才是真的樹功能了。~每個樹都有唯一的一個樹根,及tree.level=0,表示樹根,其他的都算是節(jié)點。創(chuàng)建樹根和樹節(jié)點方法一樣,只是level表示的值不一樣。一定要注意定義樹的變量:treeviewitemltv_current我們把它想成一個結構體類型的緩沖區(qū)變量。當我們對這個變量的屬性定義好后,用Insertitemfirst()就能將這個變量作為一個節(jié)點實例化,同時返回該實例的句柄。此時我們在取修改該變量是不會改變原句柄節(jié)點的,除非再次用Setitem()才能對該節(jié)點操作,用insertitemfirst()只會實例化另外一個節(jié)點。Constructor事件:該事件在控件創(chuàng)建時觸發(fā)選中該事件主要用來插入第一層TreeViewItem項,這樣用戶一進入檢索界面,第一層信息項就會出現(xiàn)在控件中。ItemPopulate事件:該事件在某TreeViewItem項第一次展開時觸發(fā),觸發(fā)的同時系統(tǒng)會將該TreeViewItem項的句柄通過參數(shù)handle傳遞過來。此時就要理解了,因為打開程序就會觸發(fā)Constructor事件,我們在他里面的最后如果用了expanditem()的話,則如果有子節(jié)點就會自動展開。此時,如果我們在ItemPopulate事件中設置了子節(jié)點,則因為Constructor事件中的expanditem會自動展開,此時馬上觸發(fā)該事件,而且會根據(jù)是哪個節(jié)點觸發(fā)了該節(jié)點的展開事件從將其句柄傳過來,所以一定要注意代碼和事件執(zhí)行的流程。Handle()ReturnvalueLong.Returnsthehandleofobjectname.IfobjectnameisanapplicationandpreviousisTRUE,Handlereturns0ifthereisnopreviousinstance.Ifobjectnamecannotbereferencedduringexecution,Handlereturns0(forexample,ifobjectnameisawindowandisnotopen). 可見,只有是可見的實例才有句柄。 Pb中動態(tài)調(diào)用函數(shù)目前流行的大部分應用程序中都提供了Undo功能,在PowerBuilder中也可以利用Undo()函數(shù)實現(xiàn)該功能。Undo()函數(shù)可用于DataWindow,EditMask,MultiLineEdit,RichTextEdit和SingleLineEdit對象,如果只對某一個對象進行Undo操作,只需在Undo菜單項的單擊事件中鍵入如下腳本:Objectname.undo(),但是當窗口中有多個對象,我們在編寫腳本時并不知道要對哪個對象執(zhí)行undo()操作

如何解決這一問題呢?在PowerBuilder中,undo()等函數(shù)只能用于可視對象,而所有可視對象均繼承自系統(tǒng)對象類GraphicObject。因此我們可以定義一個GraphicObject對象的實例變量go_object,等到運行時再用getfocus()函數(shù)確定具體操作對象。然后用Typeof()函數(shù)確定當前對象的類型,再用Choosecase語句根據(jù)不同的類型引用不同的實例變量,代碼如下:記住,用go_object=getfocus()得到的是當前得到焦點對象的引用。

graphicobjectgo_object

DataWindowdw_object

EditMaskem_object

MultiLineEditmle_object

RichTextEditrte_object

SingleLineEditsle_object

go_object=getfocus()

choosecaseTypeOf(go_object)

caseDataWindow!

dw_object=go_object

dw_object.undo()

caseEditMask!

em_object=go_object

em_object.undo()

caseMultiLineEdit!

mle_object=go_object

mle_object.undo()

caseRichTextEdit!

rte_object=go_object

rte_object.undo()

caseSingleLineEdit!

sle_object=go_object

sle_object.undo()

caseelse

messagebox("Error","Cannotundo")

endchoose

其實我們可以用動態(tài)調(diào)用函數(shù)的方法簡單地解決這一問題(只需三行代碼),即對GraphicObject對象調(diào)用undo()函數(shù),然后在函數(shù)名前加上關鍵字Dynamic。因為對象類GraphicObject并沒有undo()這個對象函數(shù),如果不加關鍵字Dynamic,編譯時就會出現(xiàn)錯誤。使用了Dynamic關鍵字,PowerBuilder在編譯時不檢查該函數(shù)和所用參數(shù)的有效性,而到腳本運行時才去檢查該函數(shù)。代碼如下:

GraphicObjectgo_object

go_object=getfocus()

go_object.dynamicundo()parentwindow.postdynamiceventue_whole_input()這是一個目錄的單擊事件,可見,此時這個目錄還沒有依賴窗口,所以就要用動態(tài)的觸發(fā)以后依賴窗口中的事件。當我們在數(shù)據(jù)窗口對象中給每個字段的backcolour填寫了表達式時,一般就會在clicked事件中對數(shù)據(jù)窗口的每行顯示出來,但是,有的時候會顯示不出來,那是因為沒有在數(shù)據(jù)窗口對象中給相應的字段設置Taborder順序值,此時,他們的order值是0的,故相當于沒有焦點,相當與沒有做操作。同時,當我們的某個字段是下拉列表或數(shù)據(jù)窗口時,點擊時會出現(xiàn)下拉框,為了避免這種情況,我們也可以將相應字段的order值設為0,此時只會顯示當前值了。在我們在數(shù)據(jù)窗口中給某個字段設定下拉列表或數(shù)據(jù)窗口時,可以設置實際值,和顯示值,注意其中的關聯(lián):比如說,要顯示某個人的名字,但是在數(shù)據(jù)里是用id來表示它,我們檢索出來的也是id,但是我們要得到它的名字,我們就可以考慮用該字段關聯(lián)相應的數(shù)據(jù)窗口對象,注意:字段關聯(lián)的是數(shù)據(jù)窗口對象而不是數(shù)據(jù)窗口。所以,我們新建一個數(shù)據(jù)窗口對象,選擇2個字段,id和name,用id作為實際值,用name作為顯示值。本來這個數(shù)據(jù)窗口顯示的值為5,用了5后,這個數(shù)據(jù)窗口對象就根據(jù)5來找到對象的人名將其顯示出來。實質(zhì)上實際數(shù)據(jù)是沒有變的,但是相當與用了2個數(shù)據(jù)窗口對象查詢語句。一定要注意在使用數(shù)據(jù)窗口的列名來取值時,這個列名一定是數(shù)據(jù)窗口對象的內(nèi)容名,因為從數(shù)據(jù)庫中建數(shù)據(jù)窗口對象時,當一次引用2個表時,他們的字段名字都會改變,變?yōu)楸砻幼侄蚊?,所以一定要注意。我們進行連表創(chuàng)建數(shù)據(jù)窗口對象時,他們其實就是一個select查詢語句,連表時,就是用一中關聯(lián)將他們聯(lián)系起來,這樣就會顯示對應的值比如:表1中的id唯一,但是這個id創(chuàng)建了另一個表的多個use_id 表2中的user_id所以,當我們連表時,就給這2個字段指名關系,則在查詢時,就會顯示對應的數(shù)據(jù)值。 我們對數(shù)據(jù)窗口用retrieve()語句,其實就是執(zhí)行的數(shù)據(jù)窗口對象的sql語句,所以,能檢索什么出來主要看數(shù)據(jù)窗口對象的本身的sql語句。重點:在用動態(tài)select語句時,一定要分清類型,此時的select語句中的字段是不用象查詢時要在變量名前加冒號的(:).ls_filter="where(ctsq_createtime>='"+string(ld_begindate,"yyyy-mm-dd")+"'andctsq_createtime<='"+string(ld_enddate,"yyyy-mm-dd")+"')"+”anduser_id=”string(llong_id)+“anduer_name=”+ls_name從上面就要看出,這個select的動態(tài)語句,本身就是string類型的,所以不管是上面變量,都要現(xiàn)變?yōu)閟tring類型才能寫入,其次,表的字段名字是沒有修飾的,而且類型任意,所以,而此時字段的類型就要和變量的類型一致,因為開始的string的操作值是為將其能夠?qū)懭脒@個string類型的語句中,而在后臺操作時,它就是一條實際的查詢語句,類型就要匹配所以,其實這是2個層次的類型匹配:一個是語句的string類型的匹配一個是字段屬性的匹配。datawindowchild ldw_childdw_data.getchild("cllx",ldw_child)“cllx”是指定子數(shù)據(jù)窗口所在的列。ldw_child.settrans(sqlca)ldw_child.retrieve()事先就檢索出來。注意,getchild()得到的是數(shù)據(jù)窗口對象的引用。此時,就要注意,當我們在主數(shù)據(jù)窗口中引用子數(shù)據(jù)窗口時,不管主的是不是有sql語句:要注意,在子數(shù)據(jù)列上能否自動檢索到數(shù)據(jù)有2中辦法:在數(shù)據(jù)窗口對象Edit畫板中有Autoretrieve選項,夠上后就能自動檢索到數(shù)據(jù),但是前提是它與事務對象連接了,因為這個選項只是起到檢索的作用??梢岳蒙鲜?.中的getchild得到子的引用,再進行連接并檢索。此時如果主的與事務對象slqca相連,則子數(shù)據(jù)窗口不用與事務對象相連也能顯示出數(shù)據(jù)。如果主的沒有與事務對象相連,但是子數(shù)據(jù)窗口與事務對象相連了,則也會顯示出數(shù)據(jù)。注意:當我們建的數(shù)據(jù)窗口對象是沒有sql語句時,則我們不用使其對應的數(shù)據(jù)窗口與事務對象相連,因為與事務對象相連就是能檢索到數(shù)據(jù),能檢索到數(shù)據(jù)就是因為有select的sql語句,本身就沒有sql語句,那么用事務對象也沒用,此時,我們有幾種辦法給其賦值:一般在腳本中用setitem()給其賦值。利用下啦數(shù)據(jù)框或下拉列表來賦值。有數(shù)據(jù)窗口對象時,則動態(tài)建sql查詢條件語句用:dw_result.setsqlselect(select)沒有數(shù)據(jù)窗口對象時,則先建數(shù)據(jù)窗口對象(源),再建sql查詢條件。我們知道,數(shù)據(jù)窗口對象本身是源,但是功能就象一條sql語句,當數(shù)據(jù)庫連接好后,在數(shù)據(jù)窗口對象畫板中就能看到這條slq語句查詢出來的數(shù)據(jù)了,但是當其與數(shù)據(jù)窗口聯(lián)合使用時,要想顯示數(shù)據(jù)就必須使相應的數(shù)據(jù)窗口與事務相連,然后再retrieve()。當我們使用動態(tài)的sql語句時,即dw_result.setsqlselect(select)時,就是為了數(shù)據(jù)窗口分配了查詢條件,只要數(shù)據(jù)窗口對象相應的字段屬性匹配,就可以檢索出相應的值。但是,我們設置的動態(tài)sql只能設置where的條件,即檢索出相應條件的數(shù)據(jù)條件,而不能改變每個字段本身的屬性,因為字段本身的屬性是數(shù)據(jù)窗口對象創(chuàng)建時源的代碼定義的,我們所建立的動態(tài)sql語句只是查詢條件。我們可以理解為,當沒有給數(shù)據(jù)窗口分配數(shù)據(jù)窗口對象時,我們動態(tài)的分配查詢語句給它,是不夠的,因為沒有顯示數(shù)據(jù)的載體,此時首先給他動態(tài)的創(chuàng)建數(shù)據(jù)窗口對象的源(實質(zhì)就是創(chuàng)建一個沒有sql查詢條件的數(shù)據(jù)窗口對象),其次再給它建sql查詢條件,即dw_result.setsqlselect(select),這時就相當與給它動態(tài)的分配了數(shù)據(jù)窗口對象,此時數(shù)據(jù)窗口連接事務對象再用retrieve()就可以檢索到相應的數(shù)據(jù)。同時,我們要注意,再動態(tài)建立sql語句時,如果有了數(shù)據(jù)窗口對象,我們只會建立好where條件,但是如果沒有數(shù)據(jù)窗口對象時,我們建立的sql查詢語句就要根數(shù)據(jù)窗口對象的源代碼相對應。 也就是說:源中有name字段,sql語句中也要有name字段,如果沒有,則都沒有。 因此,我們得到一個結論,動態(tài)的創(chuàng)建數(shù)據(jù)窗口對象時一般沒有創(chuàng)建sql查詢條件,然后再創(chuàng)建sql查詢條件才能完整的顯示出數(shù)據(jù)。我們也可以在創(chuàng)建源時同時創(chuàng)建sql查詢條件,就象在new創(chuàng)建數(shù)據(jù)窗口對象時同時創(chuàng)建。我們最好是將所有的主數(shù)據(jù)窗口與事務對象相連。避免子數(shù)據(jù)窗口沒有顯示出數(shù)據(jù)的情況。為什么加載到列的子數(shù)據(jù)窗口對象能顯示出數(shù)據(jù),而不用檢索,那是因為在屬性頁面上點擊了Autoretrieve。我們一定要注意數(shù)據(jù)窗口對象的名字問題:標題名字內(nèi)容名字內(nèi)容名字對應的在數(shù)據(jù)庫中的名字。標題名字比內(nèi)容名字多了_t。記住,內(nèi)容名字不一定和數(shù)據(jù)庫中相應的字段名字一樣:當只有一個表時,他們是一樣的當是多表聯(lián)合時則內(nèi)容名字和數(shù)據(jù)庫名字是不一樣的。在數(shù)據(jù)窗口對象畫板中我們就可以看見內(nèi)容名字和對象的數(shù)據(jù)庫名字,此時就要注意:當我們對數(shù)據(jù)窗口進行操作時,即getitemstring()就要用內(nèi)容的名字來操作代碼。但是我們是對數(shù)據(jù)庫進行操作時,即象select語句時,就要用對應的數(shù)據(jù)庫的名字來操作。所以,一定要注意名字問題,同時注意多表聯(lián)合使用的情況。//動態(tài)數(shù)據(jù)窗口

數(shù)據(jù)窗口對象語法:

ls_syntax=sqlca.syntaxFromSql('selectkind,namefromtab_t','style(type=tabular)',ls_err1)

dw_1.create(ls_syntax,ls_err2)

dw_1.setTransObject(sqlca)

dw_1.retrieve()//在程序中動態(tài)設定列的編輯風格為下拉數(shù)據(jù)窗口(DropDownDataWindow)

//假設所設定列為部門號"department_id",相關連的子數(shù)據(jù)窗口為"d_dddw_dep",

//顯示列為部門名稱"dept_name",數(shù)據(jù)列為部門號"dept_id",實現(xiàn)方法如下:

dw_1.Modify("department_id.DDDW.Name=d_dddw_dep")

dw_1.Modify("department_id.DDDW.DisplayColumn='dept_name'")

//或:

dw_1.object.department_="d_dddw_dep"

dw_1.object.department_id.DDDW.DisplayColumn="dept_name"

//注:PowerBuilder有一個小工具DWSyntax(程序名為:dwsyn60.exe),提供了獲得及修改數(shù)據(jù)窗口、列等的各項屬性值的語法,對編程非常有幫助。上述腳本在DWSyntax中都能找到。//如何將COLUMN的顯示風格在EDIT、DDDW、DDLB之間相互切換:

(1)切換成DDDW:

dw_1.Modify("#1.dddw.Name='dddw_jg'")

dw_1.Modify("#1.dddw.DisplayColumn='name_jg'")

dw_1.Modify("#1.dddw.DataColumn='id_jg'")

(2)切換成DDLB:

dw_1.Modify("#1.ddlb.case='any'")

dw_1.Object.#1.Values="red~t1/white~t2"

(3)切換成EDIT:

dw_1.Modify("#1.edit.case='any'")

dw_1.Modify("#1.edit.AutoSelect='Yes'")

(4)獲取當前風格:

dw_1.Describe("#1.Edit.Style")

(5)如果還不行,可能得要如下操作:

dw_1.Modify("#1.dddw.Name=''")一下;//如果符合條件,則顯示灰色的背景,否則白色;

本方法同樣可以設置該列的字體顏色:其中"column_name"為列名。

dw_1.object.column_name.background.color="16777215~tif(fromid='string',rgb(192,192,192),rgb(255,255,255))"

也可以是一行都變色:

dw_1.object.Datawindow.detail.color="16777215~tif(fromid='string',rgb(192,192,192),rgb(255,255,255))"http://超鏈接,連到指定的網(wǎng)站。

Inetlinet_base

GetContextService("Internet",linet_Base)

linet_Base.HyperlinkToURL('')

Destroy(linet_base)//如何取出DDDW中的DisplayColumn的內(nèi)容。

dw_1.describe("Evaluate('lookupdisplay(column_name)',1)")

//column_name=列名,'1'表示第一行;看看Help中的Describe我們在對MDI窗口時,打開時直接放中間用一個函數(shù),當改變窗口的大小時,就要在其Resize()事件中寫一個函數(shù)來使其按比例縮放,即改變窗口大小,同時也要改變窗口中相應控件的大小,做到比例一致。//怎樣得到字符串中漢字的個數(shù)

Fori=1toLen(aString)

ls_ch=Mid(aString,i,1)

IfAsc(ls_ch)>=128then //判斷是否是漢字可以用它的ASCII碼是否大于127來判斷。li_num++

i=i+1

Endif

Next補空行:分組表示,每多少行插入一空行來分組。

在窗口的open事件中寫如下代碼:

longli_count,li_i

li_count=dw_1.retrieve()

ifmod(li_count,25)<>0then //求余

forli_i=1to25-mod(li_count,25)

dw_1.insertrow(0)

next

endif我們一定要注意實例變量或?qū)嵗龜?shù)組的值的滯留問題,所以,一般在相應的地方賦空。Dde是動態(tài)數(shù)據(jù)交換服務器函數(shù)。我們一定要注意不同對象的實例變量的區(qū)別,特別是在調(diào)試時注意:當在代碼中跳進一個窗口函數(shù)時,窗口對象定義的實例變量和這個函數(shù)中用到的實例變量是一致的,因為這個函數(shù)本身就屬于這個窗口。但是當我們在代碼中跳進一個用戶函數(shù)時,此時里面所有的實例變量都是屬于該對象的,特別注意用戶對象中定義的變量都是以i開頭的,很容易以為是窗口對象中定義的實例變量,有時候名字都會一樣,此時就一定要注意了,這是不一樣的,要區(qū)別。子對象繼承父對象時,用Call可以引用父對象的屬性和方法當一個主窗口中,放了一個一級自定義對象,一級中又有二級自定義子對象,此時就會有3個層次的機構,此時,大的都可以對小的屬性和事件進行操作,但是小的卻不能對大的屬性和事件進行操作。Commit:當你對數(shù)據(jù)庫的值進行修改或增加的時候,在PB中要進行提交。可以看做是將數(shù)據(jù)庫中的數(shù)據(jù)進行保存操作。所以,修改一次,一般就作一次Commit,多次修改,就多次提交。這樣就避免中間修改了,后面要用到該數(shù)據(jù)時進行修改時而找不到正確的數(shù)據(jù)。當我們在PB中進行一次修改數(shù)據(jù)的時候,數(shù)據(jù)庫中也會做修改,但是沒有commit的數(shù)據(jù)在數(shù)據(jù)庫查看不到,但是PB中可以將修改后的數(shù)據(jù)查

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論