1. 程式人生 > >form開發筆記(一)

form開發筆記(一)

1、開篇

    我在專案上的首個form開發是雜項費用定義介面的開發。下面是我的開發筆記。

2、開發步驟

    專案上有關於form的標準模板,這個模板是整合了所有與具體開發無關的項,比如新增folder函式庫,物件組,以及folder特有的item等等,省卻了我們很多的麻煩,而這些在黃老的folder開發指南中有詳細的步驟,不詳述。

總體的開發步驟如下:

1)根據基表寫檢視,注意命名,視圖裡用的是不帶all的同義詞,檢視具有MOAC安全性。 

2)給form命名、修改form的PRE-FORM、WHEN-NEW-FORM-INSTANCE 觸發器            

3)基於檢視建立block;建立對應的prompt塊                                            

4)建立畫布、把第三步生成的item發到畫布上                                 

5)修改PROMPT 名,拖拽生成                                                 

6)生成檢視增刪改 package cux_0_plsql_autocreate.form_view_iud          

7)編寫lov、block trigger程式碼。                                           

其中,block級trigger是對主從塊新增四個on- 開頭的trigger,要建立以塊命令的private包,trigger呼叫包中的過程,實現檢視的增刪查改

3、預備役基礎知識

    在我們做form開發的時候,需要弄明白的一點就是:基表,檢視以及form三者的關係,要明白它們三者之間是如何進行聯絡的:資料庫基表的資料是如何顯示到前臺介面,我們在form中錄入的資料又是如何儲存到後臺資料庫中的。

3.1、基表,檢視和form的關係——從後臺基表到form前臺介面;

   

    首先,每一個form介面都必然對應一個相應的後臺基表,這個基表是儲存所有前臺顯示資料相關的欄位,它儲存的是對應的id和code。

    這些id和code如何展現到前臺呢?

通過檢視;我們新建的各個block塊很多都是基於檢視的;

Form是客戶化的,後臺儲存的id和code可能開發人員都不清楚每一個具體代表什麼意思,因此在建立檢視的時候會根據這些欄位關聯到其他的表,從這些表中取出id、code相對應的中文名稱。檢視是做什麼用的?實際開發中我們基於檢視view建立資料塊,我理解為:檢視只是專門用來在form前臺呈現資料

給使用者看的,沒有其他的作用。我們在前臺所做的增刪查改四種操作,只有會用到檢視,靜態的檢視,其他三種會引起資料庫資料改變的動態操作是通過呼叫private包內的過程實現的,和檢視沒有任何的關係。沒做form之前我還以為前臺資料會通過檢視進行反編譯出對應的後臺欄位,我果然太天真了~~~現在明白:檢視只是單純的顯示資料用~

    而我們在前臺錄入的資料,在點選儲存的時候,是通過呼叫我們寫的對應的private包(後面詳述)實現的對資料的增刪改~

3.2、lov列和list的區別

    Lov列和List都可以實現指定資料的範圍進行選擇。

它們的共同點:

a.都可以供使用者選擇指定範圍的資料;

    b.Lov和list對資料的修改都是在form層中進行修改,對view是沒有影響的,只有在點選儲存的時候,會觸發觸發器呼叫private的包,對基表進行DML操作,從而將我們所做的修改儲存到基本表中;

它們的區別:

區別一:

lov只是在使用者修改資料的時候會用到,比如要修改一個物料編碼,我點開lov,選擇一個進行修改;在不進行修改操作的情況下,只是查詢資料,那麼lov本身是不起任何作用的; 而且我們在lov中顯示的值一般都會在檢視中查找出來;

而list在顯示資料的時候,一直在生效;可以把form介面分為form層的前臺和後臺,前臺顯示資料,後臺存放對應的值;同樣的一個值列表:

 中文名:“按通知單行”對應基表中儲存的欄位: MEMOLINE

如果使用lov值列表實現,那麼前臺我們見到的資料項只有一個,但是後臺卻需要兩個資料項來儲存資料;  我們需要在form中建立兩個item,其中一個存放中文名:用來在前臺顯示資料;另一個存放對應的code值:在增改操作的時候寫入資料庫時用到;

如果使用list值列表,那麼我們前臺見到的資料項只有一個,後臺需要的資料項也只要一個;list本身相當於是在前臺和後臺中間建立了一個轉換器,我們在後臺儲存的code值經過list轉換器會自動轉換成對應的中文名,顯示到前臺介面;也就是說form後臺儲存的是code值,但是我們在前臺看到的卻是對應的中文;

可以參照list定義值的結構進行理解:

它就是一個翻譯軟體~


因此在建立檢視的時候,我們沒有必要把去關聯N多張表,把code對應的中文名取出來,而是可以直接在form層使用list值列表定義其對應的中文名;

一般在快速編碼中會用到這種方法;見知識點XX

注意,如果某個item屬性是list,它的列表值是快速編碼中的值,需要呼叫一個函式,難點:函式的作用就是將我們編寫的類似lov的sql語句的records值指定給list列表值,同時,我們要給這個list指定一個初始值,不然編譯時會報錯。這時候,我們點選下拉列表,列表值就是我們定義的初始值和records值;

區別二:lov列表值可以指定返回多個item,而list列表值只能返回值給當前的item;

3.3  moac安全性控制與按ou遮蔽

我對moac還沒有怎麼深入的研究過:目前我對moac的理解是,在form中,會啟用moac進行安全性控制;

我們所開啟的form,都是定義在某一個具體的職責之下的,但並不是每一個職責都可以訪問到所有的後臺資料;比如,一個大公司,它在北京,上海都有分公司,它們共用一個ebs系統,資料庫中儲存了北京公司和上海公司的業務資料;

現在,系統中定義了兩個職責:北京分公司辦事處和上海分公司辦事處;

進入北京分公司辦事處的操作人員在對資料庫中的資料進行修改時,是不允許對上海分公司的資料進行任何操作的,嚴格上來說,北京分公司的人在查詢資料的時候,上海分公司的資料都不應該顯示出來;那麼,這個是如何實現的呢?

通過定義安全性配置檔案,實現moac安全性控制;

Moac安全性配置檔案中會定義該職責能夠訪問哪些ou,在我們進行查詢資料的時候,從資料庫中查詢出來的資料,會經過配置檔案的過濾,過濾掉所有沒有定義的ou的資料,只把該職責下允許訪問的資料顯示出來;


按Ou遮蔽不是指在語句的條件中進行所謂的指定org_id=塊.org_id,這等價於moac初始化;

舉個例子:在多ou的情況下,比如:訂單超級使用者下有兩個ou:江蘇和浙江,後臺表中江蘇的ou下定義了費用型別,有四個值;而浙江下沒有定義費用型別;

此時,在form中,即使你選定的ou是浙江,在點選lov值列表選擇費用型別的時候,即使浙江並沒有定義,但是依然可以選出四個費用型別;可以理解為,這個費用型別是該職責下所有的ou所公用的;唯一的區別是:要在配置檔案中定義好該ou是否可以訪問其他的ou;預設的是當前的ou只能訪問當前ou的資料;

所謂的跨ou的業務:是指在同一個訂單型別定義介面,在選擇訂單型別的時候,我可以選擇多個不同的ou資料,就是說同一個頁面,有多個ou的記錄,當然,儲存到資料庫中的時候可以根據org_id進行指定; 就像下面的資料,多ou;

像我一開始的時候,指定lov值列表是使用的:

Where org_id=fnd_profile.value('org_id');

這樣取的是當前的ou職責下,form級的預設org_id,對於多ou的情況下,那麼該lov值只能選擇到當前form級org_id對應的ou下表中定義的資料,當我們的行選擇的是另一個ou的時候,因為form級的預設ou是不變的,塊級的ou只對當前塊的當前記錄有效,所以如果上面那樣指定的話,lov返回的是上一行的相同的結果;這樣,就無法實現多ou的智慧判斷取值,應該使用:塊名.org_id,這樣取的就是資料塊的值了;

一般一個職責下有多個ou,我們在進入和ou有關的form的時候,會彈出一個值列表,讓我們選擇是在哪個ou下,我們進入後,當前的form級org_id就是該org_id,如果當前form支援多ou,那麼在選擇ou的時候,我們可以選擇其他的org_id,也就是塊級的org_id;form級一般有一個預設的org_id,在配置檔案中進行定義;

3.4、安全性配置檔案的定義和分配

分配安全性配置檔案

路徑:系統管理員配置檔案系統:指定責任、MO%配置檔案,可進行分配,定義預設的業務實體;

如何檢視、定義moac對應的配置檔案內容?  B02_CB000_華潤啤酒

職責:%HR%超級使用者%--安全性配置檔案   可檢視和定義配置檔案中定義的ou

我所在專案上職責劃分很清晰,基本是的單OU

4、開發步驟詳解

4.1、根據基表寫檢視

檢視必須具有moac安全性,也就是說對基表的引用必須使用同義詞,moac對ou資料的訪問控制可以理解為:在form介面中我們使用Ctrl+F11,從all表中查詢出所有資料後,因為moac安全性配置檔案,會將所有不在配置檔案中的ou的資料全部自動過濾掉,只留下符合條件的ou下的資料;

建表:

我們所做的form開發,首先判斷是否需要新建資料庫表?如果需要建表,判斷是否有org_id欄位,需要ou遮蔽?一般如果表中具有org_id即業務實體欄位,都是受moac安全性控制,建表的時候需要建一個帶_ALL的表(CUX_2_PX_MIXFEES_TYPES_ALL)和一個不帶_ALL的同義詞(CUX_2_PX_MIXFEES_TYPES),建立同義詞的sql語句:

CREATESYNONYMAPPS.CUX_2_PX_MIXFEES_TYPES FORCUX.CUX_2_PX_MIXFEES_TYPES_ALL;

BEGIN

dbms_rls.add_policy(object_name    => 'CUX_2_PX_MIXFEES_TYPES',

policy_name     => 'ORG_SEC',

policy_function => 'MO_GLOBAL.ORG_SECURITY',

policy_type     => dbms_rls.shared_context_sensitive);

END;

建檢視:

當我們建好或找到我們所需要的基表以後,可以開始寫檢視了。

檢視中所需要包含的欄位,包括:

Rowid欄位+基表中的所有原始欄位+form前臺顯示欄位

其中,如果需要ou遮蔽,基表需要使用同義詞,從表不用;


所謂的moac安全性會在查詢資料的時候自動過濾掉所有不在配置檔案中定義的ou資料,只保留定義了的ou的檢視資料;

注意:正式的檢視中不能包含中文,否則程式遷移的時候會出現問題。如果需要有中文作為參考,可考慮使用兩個版本

4.2、給form命名、修改form的PRE-FORM、WHEN-NEW-FORM-INSTANCE觸發器

指定觸發器中的form為我們自己編寫的form檔名,其中:

在對某個form進行修改的時候,修改完成以後最好在PRE-FORM觸發器中修改日期為當前日期,

'$Date: 2014/10/2 10:09  $'

作用:可以在form頁面檢視當前form的最後修改日期;當然,這不強制;屬於編碼習慣的問題;


4.3、基於檢視建立block;

基於檢視用嚮導建立block塊,從模板中將block級trigger、兩個item拖拽過來(FOLDER_SWITCHER,CURRENT_RECORD_INDICATOR)

需要注意的地方:

問題點:FRM-10757報錯:No masterdata blocks are available.

在建立和其他塊關聯的時候,可能會報這個錯誤;

原因:勾選了auto-join data blocks,去掉後可以選擇自己擬定關聯條件;

4.4、建立畫布、把第三步生成的item發到畫布上

建立堆疊畫布,將第三步建立的塊的item放置到該畫布上,屬性設定參照其他form模板;

唯一麻煩的就是佈局的設定,尤其是堆疊畫布,調整相對位置;

 

4.5、建立對應的prompt塊,拖拽生成;

建立對應的Prompt塊,item寬度、順序和block中對應的item一樣~

從模板中將folder特有的6個item拖拽過來,並分配order by1/2/3到畫布;

知識點:folder排序:prompt中的 order by

Order_by 按鈕可實現folder記錄的自動排序,無論放在哪個畫布上都無所謂,但是必須放置在某個畫布上,不能讓Canvas屬性為Null,否則報錯:FRM-41014:不能設定空畫布項;


可以排序的總是前三個基於table的列,Order by 1/2/3針對的form介面前3列資料項(對應prompt的前三個item);

4.6、生成檢視增刪改的package  cux_0_plsql_autocreate.form_view_iud

Form中,每一個數據塊,我們在前臺介面所做的修改,如果想要將資料儲存到後臺,需要呼叫一個private包,包裡包含四個過程:

PACKAGEmixfees_header_private IS

PROCEDUREinsert_row;

PROCEDURElock_row;

PROCEDUREupdate_row;

PROCEDUREdelete_row;

ENDmixfees_header_private;

這個包裡的所有程式碼都是呼叫系統的一個包自動生成的(這個包是我們公司自己寫的,其他專案上不一定叫做這個名字,以專案上的為準);

知識點1:package的開發規範

在form開發中,一般都不會直接在tirgger中寫死函式,而是建立一個同名的包,裡面放置各trigger對應的處理過程或函式,然後進行呼叫,比如:

包名規範如下:

知識點2:檢視增刪改過程函式的生成~

cux_0_plsql_autocreate.form_view_iud,右鍵test輸入塊名表名所有者CUX以及主鍵

自動生成包體注意直接生成的檔案有小bug修改body中的用到的序列改成不帶ALLsequence

執行後,在DBMS Output檢視輸出


將對應的包和包體部分程式碼直接複製過去就好~

4.7、編寫lov、block trigger程式碼。

整個form開發的難點有兩個:一個是佈局:麻煩,另外一個就是trigger的編寫;

知識點1:lov中隱藏的返回值;

在之前培訓時候我做的form,基於表,而且也只是做form的前臺介面,不管後臺的實現;在實際的專案中,我們要做的不是form,而是一個功能,用form實現的功能,能夠實現對後臺資料的增刪查改等操作的有意義的form;

基於檢視和基於表建立block塊的區別就在於:基於表,我們block中的每一個欄位都能夠和資料庫中基表的欄位相一致;而基於檢視,block中會多出幾項,這幾項是我們根據基表中的資料關聯到其他表中取出來,用來展示資料用的;

比如:費用型別的一個lov,我們在前臺點選lov值列表,返回一個meaning值,而我們基表中儲存的是該meaning值對應的code;我們如何將這個code值儲存到後臺中;方法:雖然在前臺頁面看lov值只有一個meaning,實際上,該值列表隱藏了一個code欄位,它的顯示長度為0;

前臺介面:


對應的sql語句:

SELECT flv.lookup_code,flv.meaning

FROMfnd_lookup_values_vl flv

WHEREflv.lookup_type = 'CRC_B02_PX_EXPENSE_TYPE'

ANDSYSDATEBETWEENflv.start_date_active ANDnvl(flv.end_date_active,SYSDATE)

ANDflv.enabled_flag='Y'

關於返回值lov中選定以後返回值不僅僅只是返回在介面上可見的item對於未在畫布上顯示的欄位也需要返回值這部分未顯示的欄位是對應後臺表中的欄位在儲存插入資料時用到。重要~

知識點2:頭行結構中,行item與頭item相關項的兩種賦值方法

針對頭行結構的行,我們一般需要在行表中儲存一個頭表的主鍵header_Id,以此將頭表和行表相關聯起來,同時如果頭中涉及到了ou,那麼行表很可能需要儲存org_Id(按OU遮蔽);對於ou,頭表我們可以通過lov值列表中選擇好後,將它對應的org_id返回給頭的org_id,方便儲存的時候將對應ou的org_id儲存到後臺表中;但是,這個返回只能指定返回給一個項;那麼,行表呢?行表中的org_id要如何指定?不止是org_id,還有其他和頭表有關的資料應該如何獲取?

方法一:通過觸發器賦值 when-create-record

當游標移動移動到行新建記錄的時候觸發行block級觸發器:when-create-record;在這裡將行表中與頭相關的項進行賦值;

 

方法二:在屬性中直接設定:Copy Value from Item

知識點3:插入和更新時的重複性驗證程式碼

這裡的要點是要弄清楚表中的唯一性條件是什麼,本開發中的行表唯一性條件是:

相同的業務實體(ou),相同的頭(m_type_id)下,term_code必須唯一

這裡的重複性驗證程式碼主要是我們插入或更新的資料不能與表中其他資料重複;

插入和更新時的最大區別:

插入,pre-insert表示在插入之前進行重複性判斷,行表的主鍵id是在插入時由序列自動生成,插入前主鍵id值為空~ NULL值和任何數值進行比較,結果依然為NULL,整個查詢語句查不出結果,會丟擲異常;因此,我們寫的pre-insert觸發器將無法生效;而且該條記錄本身還沒有存入到資料庫中,所以資料庫中所有的資料相對於該條記錄來說都是其他資料;

更新,是修改現有資料,行表的主鍵id已存在,我們要判斷其他記錄和我們當前修改的記錄的term_code是不是相同(相同ou,相同type_id下);如果有相同的term_code存在,那麼l_count結果大於0,丟擲錯誤;

 

知識點4:日曆控制元件的編寫

編寫日曆控制元件只要三步就可以設定好:

a.編寫Item的KEY-LISTVAL觸發器:calendar.show;

b.設定Item的List of Values屬性:ENABLE_LIST_LAMP

c.設定Item的Validate from List屬性:No

知識點5:日曆控制元件的高階用法:指定可選的日期範圍;

效果圖:灰掉的區域滑鼠無法選擇,對應開始日期之前的日期不可選


程式碼如下:

Calendar Package中包含一下幾個procedure:

1、Calendar.show([first_date])

顯示日期選擇列表,預設引數為空,即表示當前日期高亮,也可設定first_date指定任意日期高亮

2Calendar.setup(new_type varchar2--自定義型別,隨便取

,low_date date--可選,為此日期之前

,high_date date –-可選,為此日期之後

,sql_string varchar2) --禁止顯示的日期,可寫sql語句

--Setup必須必須在show的前面才能生效

Calendar.show;

a)calendar.setup(WEEKEND) 禁止選擇週末

注意WEEKEND引數是硬編碼為星期六和星期天的,所以不適用於所有的國家

b)calendar.setup(‘title’,null,null,<SQL>);禁止選擇SQL提取出來的日期清單

c)calendar.setup(‘title’,null,2014-01-01);只能選擇2014-01-01後的日期

d)calendar.setup(‘title’,2014-01-01,null);  只能選擇2014-01-01前的時期

要注意的一點:

如果使用了setup那麼選出的日期是不會經過lov驗證的也就是觸發不了驗證條件如果屬性validate from list選擇yes那麼滑鼠游標將無法移開

該屬性的作用是:使用者輸入的值必須在LOV第一可見列的值範圍內;

設為yes的話,選中日期會彈出如下後果;

 

但可是,如果是直接用日曆控制元件去選擇日期,因為灰掉的區域都是比開始日期小,處於不可選的狀態,OK,我們選擇的資料是肯定比開始日期大的,沒有任何問題;

但是使用者可能會作死,不用lov值,而是直接手動更改日期,因為資料是日期型別,如果輸入錯誤的型別,系統下方會自動提示型別錯誤,那麼使用者可能輸入錯誤的比開始日期小的日期,比如“2014”改成“2013”,怎麼辦?

方法:

在日期項下新增觸發器,when-validate-item新增驗證程式碼,驗證日期值的有效性;

IF event = 'WHEN-VALIDATE-ITEM'THEN

IF :mixfees_header.effective_end_date< :mixfees_header.effective_start_date THEN

fnd_message.set_name('CUX', 'CUX_2_PX_MIXFEES_DATE_E');

fnd_message.error;

RAISE form_trigger_failure;

ENDIFENDIF;

我們在日曆控制元件中做了限制但與此同時也必須編寫觸發器進行限制

知識點6:快速編碼的作用和定義

Form中用的較多的就是快速編碼,快速編碼就是定義一個型別,這個型別下面包含有數個我們自己定義的值,這些值可以自由的新增和刪除以應對不同的業務需求;快速編碼的應用很廣泛;快碼中還可以定義快碼。

我們可以方便的在快碼中新增和刪除值,比如:我定義一個快速編碼:

CRC_B02_PX_EXPENSE_TYPE

這個快速編碼的值我們可以在表fnd_lookup_values_vl中檢視到

快碼的定義路徑:應用開發員程式碼公用

目前,該快碼中只有四個費用型別,如果某一天因為業務需求變更,我們需要再新增一個型別,那麼我們可以直接在這裡修改快速編碼的值,因為直接是圖形介面,可以方便的進行定義和刪除,可以適應隨時的需求變更,而且使用者也好操作,具有很大的靈活性;在form開發中被大量使用;

例項見知識點7~

知識點7:通過快速編碼定義list值列表

需求:


倒三角選擇快碼值:即使用item的屬性是list item,顯示列表值;

 

方法:

宣告一個記錄組,定義一個block級過程define_list()在form初始化的呼叫該過程進行list值列表的初始化

程式碼: 其中enabled_flag = 'Y'表示啟用,同時要指定系統日期在有效範圍內;

一般使用快碼時都需要加上這兩個限制條件;

1、宣告一個記錄組records:  ACTIVE_POINT,該記錄組從快碼中取出相應的值,其中,這裡查詢出來的結果集與list的對應關係:meaning->ListEliments; lookup_code->List Item Value

SELECT flv.meaning,flv.lookup_code

FROMfnd_lookup_values_vl flv

WHEREflv.lookup_type = 'CRC_B02_PX_TRIGGER_POINT'

ANDflv.enabled_flag = 'Y'

ANDSYSDATEBETWEENflv.start_date_active ANDnvl(.end_date_active,SYSDATE)

2、在block級package中定義一個過程:define_list()

(因為該item是在mixfees_header塊下,所以該過程定義在該block下)

PROCEDUREdefine_list(p_record_group_name INVARCHAR2,p_block_item_name INVARCHAR2);

PROCEDUREdefine_list(p_record_group_name INVARCHAR2,p_block_item_name INVARCHAR2) IS

record_group NUMBER := 0;

BEGIN

record_group := populate_group(p_record_group_name);

populate_list(p_block_item_name, p_record_group_name);

END define_list;

3、Form級triggerWHEN-NEW-FORM-INSTANCE中呼叫過程,form載入時初始化值列表

IF event = 'WHEN-NEW-FORM-INSTANCE'THEN

mixfees_header.define_list(p_record_group_name => 'ACTIVE_POINT',

      p_block_item_name   => 'MIXFEES_HEADER.ACTIVE_POINT_CODE');

.. .. ..

ELSIF event = 'PRE-FORM'THEN

完成;

注意:我們如果是使用快碼定義list值列表,需要在兩處地方進行定義:

a. 指定Elements inList ,該項值至少有一個,絕不能為空,否則報錯;

一般是從快速編碼中選定一個已存在的值放在這裡;

b. 指定Initial Value;否則編譯時會報錯:FRM-30188

一般,我們指定的初始值是快碼中對應的某一個值~ 必須賦初值

 

知識點8:記錄控制-指定塊、項不可更新和刪除

實際需求

a.不允許對記錄進行刪除;

b.一條記錄儲存後,除了“終止日期”外其他欄位均不可修改;

在Block級的WHEN-NEW-RECORD-INSTANCE中追加程式碼,判斷狀態:

如果是插入的新值,所有塊、項相應屬性設定為true;如果是更新已存在的記錄,則設定對應塊、項屬性為false;

判斷的關鍵點:有無主鍵id

控制item的屬性還可以使用:

app_item_property.set_property('MIXFEES_HEADER.END_DATE',UPDATE_ALLOWED, PROPERTY_TRUE);(這個更常用)

按照上面的程式碼,使用when-new-record-instance我們實現的實際上是要在游標選中記錄的時候,當前記錄才會變灰掉,成為不可更近狀態;但是,實際上:

經常,我們會遇到查詢出來的結果直接就是不可更新狀態:

方法:使用post_query觸發器

post_query是在查詢出結果以後觸發,每查詢出一條結果觸發一次;在這裡設定不可更新,那麼每一條查詢出來的結果直接就是不可更新狀態;

觸發器的觸發時點很重要,在實際開發過程中可以參考該篇博文,每一種操作後臺對應的是哪些觸發器:  Oracle Form觸發器執行順序

http://www.cnblogs.com/quanweiru/archive/2012/12/28/2837148.html

知識點9:lov的item值清空時,清空相關聯的資料;clear 與:=null

比如該列允許為空值,它還關聯了一列code供後臺對應資料用,我從lov中選擇一項,返回一個值給該列,同時,返回一個code給另一個item;忽然,我又不想填資料了,於是我把它選為了空值,但是因為空值不觸發驗證,所以實際上另一個item依然儲存的是前一個值對應的code;

這時候,如果我們點選儲存,那麼再度查詢的時候,你會驚奇的發現,該列居然有值!!!明明我之前是置為空值了;

這種和當前列有關聯的項,在該列置空的同時,應該將所有和它關聯到的列儲存的欄位clear掉;

什麼時候需要使用該clear程式碼?

一種:關聯的項前臺會顯示;

當選中lov值,前臺自動帶出一溜兒值顯示在介面上,比如我選擇訂單型別,後面自動帶出型別的description;如果該lov被置空,因為空值不觸發驗證,所以,其他的值比如description不會自動發生改變,你會發現:lov值為空,但是卻有對應的description。

此時:需要在when-validate-item中用程式碼直接手動將它關聯的項置為null

when xx isnullthen xx.xx  := null

另一種:是隻清空後臺儲存的code

使用clear清空資料,是指那些不在form前臺顯示的那些孤傲的,隱藏的,lov顯示長度為0的欄位值,可以使用clear函式幫助清空;

比如前臺我顯示的是型別的中文名,但是我後臺儲存的是對應的code值,在前臺lov中選擇值後除了返回一箇中文名成給當前項以外,還會返回一個code值給code項,供插入資料的時候用;這時候,如果我們選中了一個型別,它對應的code是MIXFEE_CODE,此時,我們把型別值置空,對應的code值依然儲存的是MIXFEE_CODE ,這不合理;

呼叫:app_field.clear_dependent_fields()

最好每一個存在關聯的項都加上這個程式碼,即使該項是必輸,這是為了養成良好的編碼規範;

知識點10:頭行結構,要求行:第一行必輸?

在頭中新增blocktrigger:pre-insert插入之前進行判斷如果行的值為空則報錯

ELSIF event = 'PRE-INSERT'THEN

IF:MIXFEES_LINES.TERM ISNULLTHEN

fnd_message.set_name('CUX', 'CUX_2_PX_MIXFEES_TERM_NULL_E');

fnd_message.error;

RAISEform_trigger_failure;

ENDIF;

知識點11:訊息定義,測試,彈出訊息名而不是訊息內容

 

訊息定義完成後必須跑一個請求才能生效:應用開發員-工具欄檢視-請求-提交新請求--選擇生成資訊--填寫語言和應用產品(cus)

每次定義完訊息,都要跑一次請求,中英文語言環境都要;退出form後再進,可生效;

知識點12:修改後臺欄位,對應三層改變:表,檢視和form;

遇到需要修改後臺欄位,一旦修改,那麼與之關聯的需要修改檢視,form前臺:注意form中的增加的欄位不要用嚮導建立,在已經定義佈局好的form中,如果遇到因為後臺欄位的變化而修改對應item,使用嚮導會打亂已有的佈局~直接修改item的name和後臺對應的資料庫欄位:

form介面和資料庫後臺的欄位的對映關係是在database屬性中的ColumnName中建立的,修改了ColumnName對應的後臺欄位,那麼該項與後臺欄位的對映關係也隨之改變;所以我們無需做太多的改變,只需要修改item的屬性即可:

例項: 資料庫後臺原本存的是MIXFEES_TYPE_ID ,現變更需求,儲存MIXFEES_TYPE_CODE ,我需要做三層改變:

a.表    : 首先是修改資料庫後臺欄位,我用的比較極端的方式,直接刪表重建;也可以直接使用語句修改列屬性;我是因為裡面本身沒有資料,所以簡單粗暴幹掉它;

b.檢視層: 因為後臺欄位發生改變,對應的我需要修改我建立的檢視;因為該列在檢視中的作用有限;

c.form層: 在form層顯示的只有meaning和enabled_flag,

其中meaning通過lov選擇後會返回code值給該code項,以便在進行資料插入、更新時修改資料庫表資料;要做的修改如下:

修改code對應的item名,修改屬性對應資料庫後臺列,修改型別和字元長度;

修改lov對應的records的sql語句;指定lov中欄位的返回值;

修改塊級觸發器pre-insert、pre-update中使用的原id欄位改為code,重複性驗證會用到;

修改private函式包,重新指定對應欄位;

最快的方式查詢你在哪些函式中呼叫了原有的id欄位,使用該功能最方便快捷~

over!

知識點13:FORM級org_Id與塊級org_id ——多ou下的org_id釋義

Form級org_id:在多ou的情況下,一般會指定一個預設ou,我們通過

fnd_profile.value('org_id')  這是取的form級org_id,也就是對應的預設業務實體,多ou情況下無法由這段程式碼取到其他ou的值,因此在form中不常用;

在記錄中,我們常常會取一些需要ou遮蔽的值,這時候要指定當前記錄所在的ou一般是使用塊級的org_id;

在對業務實體進行選擇的時候,受moac安全性控制,判斷條件:

SELECThou.organization_id, hou.name

FROMhr_operating_units hou

WHEREmo_global.check_access(p_org_id => hou.organization_id) = 'Y'

其中,= 'Y'是檢測ou值是否在該責任對應的moac配置檔案中;是判斷;

一開始,我在塊級判斷org_id也這樣寫:

SELECT aml.memo_line_id,aml.name, aml.description

FROMar_memo_lines_all_tl aml

WHEREaml.language = userenv('LANG')

ANDmo_global.check_access(p_org_id => aml.org_id) = 'Y'

因為沒有明白mo_global.check_access

相關推薦

form開發筆記

1、開篇     我在專案上的首個form開發是雜項費用定義介面的開發。下面是我的開發筆記。 2、開發步驟     專案上有關於form的標準模板,這個模板是整合了所有與具體開發無關的項,比如新增folder函式庫,物件組,以及folder特有的item等等,省卻了我們很

安卓開發筆記——簡單的ui介面設定以及互動設計

一、實驗題目 實驗一: 中山大學智慧健康服務平臺應用開發 實驗程式碼:傳送門:https://github.com/dick20/Android 二、實現內容 1.基本的UI介面設計 實現一個Android應用,介面呈現如圖中的效果。 要求 該介面

C# Aplayer開發筆記

最近上班很無聊,剛好在找軟體的時候發現現在好多直播,視訊軟體都是基於APlayer引擎開發的,因此產生了自己開發一個視訊播放器的想法,功能上APlayer可以滿足本地播放,網路播放,直播等功能。 APlayer介紹 引擎介紹: APlayer 媒體播放引擎是迅雷公司從 200

Web開發筆記

---vue npm install --save-dev webpack --安裝element ui npm install --save-dev element-ui --安裝axios npm install --save-dev axios

iOS 開發筆記

一  崩潰日誌       有時候我們會遇到在裝置上、模擬器上執行完好,但是上線之後會遇到閃退的問題,但是,從何處著手呢?這時iOS崩潰日誌派上用場了。在大多數情況下,你能從中瞭解到關於閃退的詳盡、有用的資訊。

JRtplib開發筆記:JRtplib簡介、JThread庫編譯

原博主部落格地址:https://blog.csdn.net/qq21497936 本文章部落格地址:https://blog.csdn.net/qq21497936/article/details/84785284          

C語言開發筆記自動轉換和強制轉換

        整型資料和實行資料之間可以進行運算,而且字元型資料可以和整型資料通用,所以整型、實型、字元型資料之間也是可以進行運算的,但在運算處理之前,不同型別的資料要事先轉換成同一種資料型別。轉換方法有兩種:自動轉換和強制轉換。 (1)自動轉換 原則: 1、若參與運

微信公眾號開發筆記:配置公眾號開發模式

寫部落格向來是直接乾貨走起,廢話不多說: 1.註冊微信公眾號就不多說了, 2.在進行配置公眾號之前先成為開發者,成為開發者需要進行身份驗證 3.進行微信公眾號的配置     1.微信AppId和AppSecret直接可以在控制平臺拿到  

海康SDK開發筆記

開發環境: Ubuntu14.04 LTS。Qt4.8 SDK版本:CH_HCNetSDK_V5.2.7.3_build20170118_Linux64 1.      先將lib下所有so檔案拷貝到QtDemo/Linux64/lib,用Qtcreator開啟QtClie

【Swift】iOS開發筆記

前言   邊開發邊學習,邊攢經驗,彙總一下記錄到這裡 宣告   歡迎轉載,但請保留文章原始出處:)   部落格園:http://www.cnblogs.com  農民伯伯: http://over140.cnblogs.com 1、隱藏/顯示密碼功能   光設定secureTextEntr

嵌入式Linux裝置驅動開發筆記

一、Linux裝置的分類 字元裝置、塊裝置、網路裝置,三種裝置之間的區別是資料的互動模式,分別為: 位元組流、資料塊、資料包。 二、VFS核心結構體 VFS核心結構體定義在”linux/fs.h”標頭檔案中。 1、struct inode結構體 記

樹莓派開發筆記 開發環境搭建

開發環境搭建 開發環境搭建 硬體準備 系統燒錄 系統配置 基本配置 其他配置 安裝開發軟體 開發環境搭建 硬體準備 SD-Card 樹莓派

HTC VIVE開發筆記使用SteamVR外掛進行基本的互動

1、獲取手柄的引用:目前沒有區分左右手柄 private SteamVR_TrackedObject trackedobj; private SteamVR_Controller.Device device; trackedobj = GetComponent<

Jpeglib開發筆記:JpegLib庫介紹、編譯、Demo和工程模板

原博主部落格地址:https://blog.csdn.net/qq21497936 本文章部落格地址:https://blog.csdn.net/qq21497936/article/details/86155043     Jpeglib開發筆記(一):JpegLi

NDK開發筆記---環境搭建

安裝NDK開發環境:   結果: 執行 cygwin ,在彈出的命令列視窗輸入: cygcheck -c cygwin 命令,會打印出當前 cygwin 的版本和執行狀       態,如果 status 是 ok 的話,則 cygwin 執行正常。       然後依次

kinect2.0開發筆記搭建環境

可以參考的開發者博文 首先是Kinect2.0對電腦硬體的要求 1、下載KinectSDKv2.0    下載地址   這個從官網上下載花費的時間巨長啊。博主是真想上傳sdk供讀者下載,可惜CSDN有70M檔案的上限要求。   下載完成後,雙擊即可安裝,博主第一次安裝

thinkphp+layui系統開發筆記——資料表格

一、參考資料:1.thinkphp: https://www.kancloud.cn/special/thinkphp5_quickstart2.layui: http://www.layui.com/doc/modules/table.html二、程式碼:主體html<

odoo8.0開發筆記:Notepad ++的自動縮排引發python的問題

OpenERP7.0開發筆記系列 問題描述:使用Notepad++編輯python程式時,會發生莫名其妙的問題,程式碼明明都一模一樣,為什麼就是得不到正確結構呢? 原因其實是因為:python對縮排很敏感,一般建議用空格來完成縮排,但是,而Notep

外掛化開發筆記代理模式

前言       外掛化開發所涉及到的技術點非常多,比如程式的啟動流程、四大元件啟動流程、ClassLoader原理、上下文Context、AMS原理、反射、代理等。本篇主要簡單介紹代理模式(實際上只是一篇學習筆記),為後面介紹外掛化實現做知識鋪墊。 一、定義   &n

libzip開發筆記:libzip庫介紹、編譯和工程模板

  前言   Qt使用一些壓縮解壓功能,選擇libzip庫,libzip庫比較原始,也是很多其他庫的基礎支撐庫。   libzip   libzip是一個C庫,用於讀取,建立和修改zip檔案。可以從資料緩衝區,檔案或直接從其他zip歸檔檔案直接複製的壓縮資料中新增檔案。在不關