본문 바로가기
프로그래밍/파워빌더

PB 관련 팁, 스크립트

by 젤리씨 2019. 9. 3.
728x90
https://cy.cyworld.com/home/22827940/post/3813843

싸이월드가 사라질가봐 위 링크에 있는 내용 가져와봤습니다.



 

 

**************************[dropdownlist 로컬변수에 담기]*****************************

FOR ll_ii = 1 TO ddlb_select.TotalItems()

  ddlb_select.SelectItem(ll_ii)

  is_ddlb_select[ll_ii] = trim(ddlb_select.text)

NEXT

 

 

**************************[dropdownlist값 받기]*****************************

ddlb_1.Item[1]

 

 

**************************[Vertical scroll 없어지지 않는 문제 pb10.1부터]*****************************

   dw_1.Object.DataWindow.Print.Preview='No'

 

 

**************************[update property]*****************************

GetSqlSelect, SetSqlSelect 문장을쓰면 UPDATE PROPERTY 가 없어지므로 다음의 문장을 통해 UPDATE PROPERTY 재생성

 

 

dw_1.Modify("DataWindow.Table.UpdateTable = ~"TB_AV030~"")

dw_1.Modify("dlr_id.Key=Yes")

dw_1.Modify("prcho_id.Key=Yes")

 

 

**************************[모든 탭오더 삭제하기]*****************************

int i, i_count

 

 

i_count = integer(dw_1.Object.DataWindow.Column.Count)

 

 

FOR i = 1 TO i_count

dw_1.SetTabOrder(i, 0)

NEXT

 

 

**************************[마이그레이션 주의사항]************************************************************************

 

 

http://cafe.naver.com/pentaeduclub/2027

 

 

**************************[HINT 힌트 인덱싱 최초값 또는 최후값 빨리 가져오기]**************************************************************

 

 

select max(camp_id)

into :ll_camp_id

from tb_ao201

 

 

 

 

SELECT /*+INDEX_DESC(TB_AO201 PK_AO201) */

       CAMP_ID

INTO   :ll_camp_id

FROM   TB_AO201

WHERE  ROWNUM = 1

 

 

**************************[editmask, 에디트마스크]**************************************************************

em_condition1.Setfocus()

em_condition1.Text = ''

 

 

IF index = 1 THEN

 em_condition1.SetMask( NumericMask!, '#########')

ELSE

 em_condition1.SetMask( StringMask!, '')

END IF

 

 

**************************[파워빌더내 프로시져 등록 및 선언]**********************************************

 

 

user object(transaction) 생성 후, 마우스 오른쪽 클릭후 local function 등록

 

 

ap에서 additional properties 클릭 후, variable types의 SQLCA를 생성한 user object 이름으로 등록

 

 

ex) sqlca.spal_ship_cmd_10('H01',gstr_user_stat.user_id,999999,999999,999999,'20','',ll_outgo_cmd_id,ld_rtn_code , ls_rtn_msg);

 

 

**************************[dw argument retrieve messagebox 출력하기]***********************************************

 messagebox("confirmation", "ls_rtn_stat_cd   : " + ls_rtn_stat_cd + "~n" + &

                            "ldt_fr_Date      : " + string(ldt_fr_date,'yyyy.mm.dd') + "~n" + &

          "ldt_end_Date     : " + string(ldt_end_date,'yyyy.mm.dd') + "~n" + &

          "ls_tm_id         : " + ls_tm_id + "~n" + &

          "ls_tm_nm         : " + ls_tm_nm + "~n" + &

          "ls_good_id       : " + ls_good_id + "~n" + &

          "ls_good_nm       : " + ls_good_nm + "~n" + &

          "ls_chg_cd        : " + ls_chg_cd + "~n" + &

          "ls_medi_mclss_id : " + ls_medi_mclss_id  )

 

 

**************************[프로시져 실행]********************************************************************************************

exucute p_magamlog

 

 

 

**************************[dw 아규먼트 전체 조회시]********************************************************************************************

 

 

where type = decode(:as_type, '00', as_type, :as_type)

 

 

OR

 

 

where type like :as_type  (※ %값을 넣으면 전체 조회)

 

 

**************************[PB SQLCODE CHECK]********************************************************************************************

 

 

SQLCODE 0   성공

        100 노데이타

        -1  에러

 

 

SQLNROWS = 처리된 로우수

 

 

(예제)

IF (SQLCA.SQLCODE <> 0) OR (SQLCA.SQLNROWS < 1) THEN

   MessageBox("Confirmation", "Insert Error"+ Sqlca.SqlErrText, StopSign!)

   ROLLBACK;

   RETURN

END IF  

 

 

**************************[색 변경, 리미트(limit), displayonly 등 컬럼 속성 변경]************************************************

흰색 255,255,255, 회색 192,192,192, 연회색 230,230,230

빨강 255,100,100, 파랑 100,100,255, 버튼색 212,208,200

 

 

dw_team_dtl.Modify("team_cd_dummy.Background.Color="+string(rgb(255,255,255)))

dw_team_dtl.Modify("team_cd.Background.Color= "+string(rgb(190,190,190)))

 

 

dw_team_id.object.team_id.background.color = rgb(212,208,200)

 

 

dw_1.Modify("col_1"+".DDDW.Name=test")

dw_1.Modify("col_1"+".DDDW.DisplayColumn='name'")

dw_1.Modify("col_1"+".DDDW.DataColumn='code'")

dw_1.Modify("col_1"+".DDDW.PercentWidth=100")

dw_1.Modify("col_1"+".DDDW.Limit= 0")

dw_1.Modify("col_1"+".DDDW.Lines= 6")

dw_1.Modify("col_1"+".DDDW.UseAsBorder=No")

dw_1.Modify("col_1"+".DDDW.AllowEdit=No")

dw_1.Modify("col_1"+".DDDW.Case=Any")

dw_1.Modify("col_1"+".DDDW.NilIsNull=Yes")

dw_1.Modify("col_1"+".DDDW.AutoRetrieve=Yes")

THIS.Modify("team_cd.edit.limit = 2 ")

 

 

dw_camp_board.object.camp_board_title.edit.displayonly   = 'NO'

 

 

dw_inquiry_detail.Object.Datawindow.VerticalScrollPosition = Integer(dw_inquiry_detail.Describe("Datawindow.VerticalScrollMaximum"))

 

 

/* 선택된 로우를 제외한 모든 로우 프로텍트!*/

dw_camp_board_lvl2.Modify("camp_board_context.Protect='0~tif(GetRow()=" + String(ll_insert_row) + ", 0 , 1)'" )

 

 

/* 조건절에 의한 컬럼 배경색 변경 */

tab_1.tabpage_2.dw_src_cust.Modify("camp_src_id.Background.Color='0~tif(mod(camp_src_id,2) = 0,"+ &

                                     string(rgb(255,100,100))+","+string(rgb(100,100,255))+")'")

 

 

**************************[선택된 로우 값 변경시키기 & 홀짝 컬러 변경 dw 컬럼의 expression script]**************************

//if(mod(getrow(),2) = 0, rgb(230,230,230),rgb(255,255,255))

//IF(currentRow()= Getrow(), RGB(238,249,255), RGB(255,255,255))

 

 

 

**************************[과거값 가져오기 dw click 이벤트]**********************************************************************

ldt_old_schd_date = datetime(dwo.Primary[row])

 

 

 

**************************[로우 값 받기]********************************************************************************************

ll_row   = THIS.GetRow()  /* 선택된 로우 */

 

 

ll_row   = THIS.GetSelectedRow(0) /* 반전된 로우 */

 

 

※ Getrow로 선택된 로우와 실제 클릭한 로우가 다를수 있다. 이 때는 Click!이벤트에서 변경할 수 있다.

 

 

  ll_getrow = THIS.GetRow()

   

  IF row <> ll_getrow THEN THIS.SetRow(row)

 

 

 

**************************[로우 반전시키기]********************************************************************************************

 

 

* 다음 문장은 dw_employee의 15번째 row를 선택한다.

dw_1.SelectRow(15, TRUE)

 

 

* dw Clicked 이벤트에 작성하며 모든 row의 반전을 해제하고 사용자가 클릭한 row를 반전 시킨다.

dw_1.SelectRow(0, FALSE)

 

 

dw_1.SelectRow(dw_1.GetClickedRow(), TRUE)

 

 

or THIS.SelectRow(this.GetClickedRow(), TRUE)

 

 

or THIS.SelectRow(row, TRUE)

 

 

 

**************************[데이터 받기]********************************************************************************************

ls_kname = this.GetItemString(ll_row, "kname")

 

 

ls_kname = this.GetItemString(dw_1.getrow(), "kname")

 

 

ls_old_kname = this.GetItemString(dw_1.getrow(), "kname", primary!, TRUE)

 

 

ls_new_kname = this.GetItemString(dw_1.getrow(), "kname", primary!, FALSE)

 

 

ls_kname = dw_1.GetItemString(1, "kname")

 

 

ll_number= dw_1.GetItemNumber(1, "number")

 

 

ldt_datetime  = dw_1.GetItemDatetime(1, "date")

 

 

ls_kname = dw_1.Object.kname[ll_row]

 

 

ls_kname = dw_1.Object.Kname[dw_1.getrow()]

 

 

 

**************************[로우 삭제]********************************************************************************************

dw_1.Deleterow(dw_1.getrow())

 

 

 

 

 

**************************[로우 삭제 for 문 형식]********************************************************************************************

기존 for문과 반대로 DW 마지막 로우번호부터 처리된다.

 

 

ll_rtn = dw_user.RowCount()

 

 

FOR ll_rtn = ll_rtn TO 1 Step -1

 

 IF dw_user.GetItemString(ll_rtn, "chk") = 'Y' THEN

  

  dw_user.DeleteRow(ll_rtn)

 

 

 END IF

 

NEXT

 

 

 

**************************[dw update]********************************************************************************************

dw_1.Update()

 

 

return값이 1이면 성공 -1은 실패

 

 

**************************[dw update 기본 스크립트]********************************************************************************************

IF dw_1.Update = 1 THEN  // 성공시 1

    COMMIT ;

    uo_msg.uf_msg("해당 자료가 성공적으로 삭제되었습니다.!!")

ELSE  // 실패시 -1

    ll_code = sqlca.sqlcode

    ls_msg  = sqlca.sqlerrtext

    ROLLBACK ;

    Messagebox("확인" + string(ll_code), "데이터 삭제중 오류" + ls_msg)

END IF

 

 

 

**************************[DW 데이터 변경]********************************************************************************************

THIS.SetItem(row,'amount',ll_amt)

 

 

dw_1.SetItem(row,"amount",ll_amt)

 

 

 

**************************[데이터 형식 변경 및 추출 함수 정리]********************************************************************************************

Choose CASE DayNumber(ls_today)

       CASE 1 ls_week = '일요일'

       CASE 2 ls_week = '월요일'

       CASE 3 ls_week = '화요일'

       CASE 4 ls_week = '수요일'

       CASE 5 ls_week = '목요일'

       CASE 6 ls_week = '금요일'

       CASE 7 ls_week = '토요일'

End Choose

 

 

ls_year = Year(ls_today)

ls_month = Month(ls_today)

ls_day = Day(ldate_today)

ls_turm = DaysAfter(2009-06-01, ls_today) //일차 구하기

Round(4.324,2) = 4.32

Mod(10,3) = 1

Abs(-38) = 38

Sign(ls_chk) = O or -1 Or 1

Len(ls_cardcd) = 10

space(1) = 공백문자 채움

upper(ls_userid) 대문자로

trim(ls_mtel) 공백제거

mid(em_fdate,1,4)+mid(em_fdate,6,2) 스트링자르기

Left("BABE RUTH", 4)            BABE

Right("BABE RUTH", 4)          RUTH

 

 

string ls_replace

long ll_pos

ll_pos = pos("java","v",1)

ls_replace = replace("java", ll_pos, len("v"), "b")

문자열 대체하기 replace

 

 

 

**************************[순차누적합계]********************************************************************************************

cumulativesum(#group for all)

 

 

 

**************************[Continue의미]********************************************************************************************

int a, b

int i = 1

a = 0

b = 0

For i to dw_1.Rowcount()

 a += 1

 IF a > 5 Then Continue

 b += 1

NEXT

 

 

 

 

 

**************************[dw에 내장된 sql을 스트링으로 받고 변경된 sql을 반영]********************************************************************************************

is_select = dw_1.Describe("DataWindow.Table.Select") /* 화면 Open시 받음 */

 

 

is_select = dw_1.GetSQLSelect() /* 상위 스크립트와 같은 수행 */

 

 

ls_select = is_select + ls_jogun

 

 

dw_1.SetSQLSelect(is_select)  /* 변경된 sql을 Set! */

 

 

**************************[uf_get_datawindow_select_non_where]********************************************************************************************

dw안의 sql을 뽑아내어 where절이 있다면 제외시켜서

sql script를 받아오는 함수

 

 

 

**************************[아규먼트가 있는 프로시져 수행]********************************************************************************************

VARIABLE ERRMSG VARCHAR2(1000);

VARIABLE AC_RETURN NUMBER;

EXECUTE P_SIZECD_UPDATE('JPWEM302', :AC_RETURN, :ERRMSG);

PRINT ERRMSG

 

 

 

 

 

**************************[데이터 처리 한계 해제]********************************************************************************************

EXECUTE IMMEDIATE " ALTER SESSION SET HASH_MULTIBLOCK_IO_COUNT = 1 ";

 

 

 

 

 

**************************[윈도우 위치변경]********************************************************************************************

윈도우명.move(x,y)

 

 

 

**************************[파워빌더9 열기]********************************************************************************************

pb9 - openworkspace - target - pbt 확장자 클릭

 

 

 

 

 

**************************[ms 서버 설치]********************************************************************************************

제어판 - 관리도구 - 이름 product / 서버 virus -

id sa / pw '' - 클라이언트구성 tcp/ip 210.113.24.75 product -

기본 db product - 데이터원본만들기 마침 - pbob mss microsoft sqlserver -

gaesung product sa '' - 시작  - microsoft sql server 엔터프라이즈 관리자 생성

 

 

**************************[박스별로 나뉘거나 그룹핑된것들별로 출력]********************************************************************************************

박스별로 나뉘거나 그룹핑된것들별로 출력하기위해선 DW의

GROUP EDIT RESET PAGE COUNT와 NEW PAGE ON GROUP BREAK를 체크 해야한다

 

 

 

 

 

**************************[Find 함수 스크립트]********************************************************************************************

[특정 로우의 값을 다음로우부터 찾을 때]

dw_1.Find("brd_grp_id = "+ string(ll_brd_grp_id) ,1,dw_1.rowcount())

 

 

ll_find = dw_src_cust.Find("UPPER(TRIM((src_cust_id))) LIKE '%" + ls_camp_cust + "%' ", ll_idx, ll_rtn)

 

 

/* dw_1안의 첫번째 로우부터 마지막 로우안에 brd_grp_id와 동일한 것 찾기 */

 

 

 

**************************[로우 또는 해당 컬럼 상태값 가져오기]********************************************************************************************

ldw_status = dw_main.GetItemStatus(ll_row,0,Primary!) // DW상태값 저장

 

 

**************************[로우 또는 해당 컬럼 상태값 변경하기]********************************************************************************************

dw_main.SetItemStatus(ll_row,0,primary!,NotModified!)

 

 

 

**************************[삭제된 로우의 값 가져오기]******************************************************************************************************************

ls_tm_id = dw_camp_tm.GetItemString(ll_idx,"tm_id",  Delete!, False )

 

 

 

**************************[특수 권한체크]******************************************************************************************************************

long ll_row, ll_rtn

dwitemstatus ldw_status // 데이터 윈도우 상태값(수정 상태)

 

 

ll_row = dw_main.getrow()

 

 

ldw_status = dw_main.GetItemStatus(ll_row,0,Primary!) // DW상태값 저장

 

 

if ldw_status = Datamodified! or ldw_status = Notmodified! then  // 기존에 저장된 값을 삭제시 타게 됨

 

 

 ll_rtn = uf_authority_check('BRD_SUPER')  // 특수권한 체크

 

 

 if ll_rtn = 0 then  // 특수권한 없음 리턴

     messagebox("삭제할 권한이 안됩니다.")

     uf_messagebox(2000186, 1)

            return

 end if

 

 

end if

 

 

 

 

 

**************************[dw의 삭제,수정된 로우 카운트]********************************************************************************************

dw_main.ModifiedCount()

dw_main.deletedcount()

 

 

 

 

 

**************************[dw의 updaet 대상 테이블 변경(update property)]**********************************************************************

 

 

dw_2.Modify("DataWindow.Table.UpdateTable = ~"GSMATIOH~"")

dw_2.modify("gsmatioh_matiodt.Key =Yes") // 업데이트 가능컬럼 선택

 

 

 

**************************[Validation 체크시 오류 발견하면 사용자에게 표시해주는 스크립트]************************************************

dw_main.ScrollToRow(ll_row)

dw_main.SetRow     (ll_row)

dw_main.SetColumn("컬럼명")

dw_main.SetFocus()

 

**************************[uo_msg_line]********************************************************************************************

sle_1.text = gstr_user_stat.user_id

sle_emp_nm.text = gstr_user_stat.emp_nm

 

 

 

 

 

 

**************************[lnd 시스템 화면 작성 예시]********************************************************************************************

open 이벤트시 dw retrieve

수정은 해당 dw의 임의이벤트 생성해서 tabsequence 활성화, dw_x.AcceptText()

검색시 해당 dw의 임의이벤트 생성해서 tabsequence 비활성화

       해당 dw안의 sql을 윈도우안의 검색조건으로 where절을 만들어 만들어

       dw_1.SetSQLSelect(ls_sql)

       dw_1.Retrieve()

       검색후

       로우가 하나일 경우      : 해당 dw 더블클릭이벤트 TriggerEvent(doubleclicked!)

       로우가 없을 경우        : 메세지

       로우가 두개 이상일 경우 : 첫번째로우를 선택

 

 

저장시 해당 dw의 상태값에 따라 나뉘어 저장스크립트 분류 (데이터 체크 wf함수)

삭제시 해당 dw의 row 삭제후 입력 검색 TriggerEvent(Clicked!)

 

 

 

 

 

**************************[메세지 질의]********************************************************************************************

ll_msg = MessageBox("Confirmation", "Do you want to check all ", Exclamation!, OKCancel!, 1)

//

//  IF ll_msg = 1 THEN

 

 

 

 

 

**************************[edit mask 객체 변경 선언]********************************************************************************************

em_1.SetMask( NumericMask!, '#######' )

em_1.SetMask( DateMask!, 'yyyy/mm/dd' )

em_1.SetMask( StringMask!, '')

 

 

m_condition_campaign.Setfocus()

em_condition_campaign.Text = ''

 

 

IF index = 1 THEN

 em_condition_campaign.SetMask( NumericMask!, '#########')

ELSE

 em_condition_campaign.SetMask( StringMask!, '')

END IF

 

 

 

 

 

 

**************************[enter 키(key 이벤트)]********************************************************************************************

IF key = KeyEnter! THEN

 cb_retrieve.TriggerEvent(Clicked!)

END IF

 

 

 

 

 

**************************[parent(부모를 의미, 보통은 메인 윈도우를 의미)]**********************************************************************

cb_save의 클릭이벤트중.. parent.TriggerEvent("ue_init")

parent는 그 부모의 속성을 따라감(예 : window의 이벤트중 ue_init)

 

 

 

 

 

 

**************************[Click 이벤트에서 row 클릭시 해당 row 선택 및 해제 기본 스크립트]************************************************

IF row < 1 then RETURN

 

 

IF THIS.IsSelected( row ) = TRUE THEN

   THIS.SelectRow( 0  , FALSE )

ELSE

   THIS.SelectRow( 0  , FALSE )

   THIS.SelectRow( row, TRUE )

END IF

 

 

THIS.SetRow( row )

 

 

/* row 반전 및 해당 컬럼 셋팅 시키는 평션 */

 

 

adw_datawindow.ScrollToRow(al_row)

adw_datawindow.SelectRow(0, FALSE)

adw_datawindow.SetRow(al_row)

adw_datawindow.SelectRow(al_row, TRUE)

adw_datawindow.SetColumn(as_column)

adw_datawindow.SetFocus()

 

 

**************************[filter의 의미 및 예시 스크립트]********************************************************************************************

dw_campaign.SetFilter( "camp_id = 2 ")

※ where 조건이라 생각하면 되지만 필터이후 다른 검색조건으로 검색해도 필터조건에 의해 걸러진 내용만 뿌려준다.

   전체조회를 하려면 다시

 

 

dw_campaign.Filter()

출력함수이며 위의 조건을 만족하는 것만 뿌려준다.

 

dw_campaign.FilteredCount() > 0

이것은 위의 조건에 만족하지 않은 로우를 카운트해줌

예 : camp_id = 2를 만족하는 로우가 총 3개중 1개였다면 로우는 1개만 출력되고 filteredcount는 2가 된다.

 

 

 

b로시작되지 않는 조건

dw_Employee.SetFilter( "Left(emp_lname, 1)=~"B~"")

dw_Employee.Filter()

 

 

필터 안하고 전체 조회하기

 

 

dw_employee.SetFilter("")

dw_employee.Filter()

 

 

 

 

 

**************************[rowsmove의 의미 및 예시 스크립트]********************************************************************************************

* 다음 문장은 dw_1의 delete 버퍼에서 첫 번째 row부터 시작하여 모든 row들을 dw_1의 primary 버퍼로 이동시킨다; 따라서 이들 row들은 삭제가 취소되는 것이다.

dw_1.RowsMove(1, dw_1.DeletedCount(), Delete!, dw_1, 1, Primary!)

 

 

 

 

 

 

**************************[rowsdiscard의 의미 및 예시 스크립트]********************************************************************************************

* 다음 문장은 dw_1 delete 버퍼에 있는 모든 row를 제거한다. 결과적으로 응용프로그램에서 나중에 dw_1.Update()를 호출한다면, DataWindow는 이들 row에 관한 SQL DELETE 문장을 DBMS에 보내지 않을 것이다.

dw_1.RowsDiscard(1, dw_1.DeletedCount(), Delete!)

 

 

 

 

 

 

**************************[dw 다단 출력하기]********************************************************************************************

window open단

string ls_colx

ls_colx = dw_detail.Object.camp_faq_sub_context.x

dw_detail.Object.datawindow.horizontalscrollsplit = ls_colx

 

 

dw property

hsplitscroll checked

 

 

**************************[listbox 내의 선택된 텍스트 저장하기]**********************************************************************

listboxname.SelectedItem ( )

 

 

 

 

 

**************************[insert 로우, 행 삽입 기본 스크립트]**********************************************************************

dw_1.insertrow(0)

로우의끝에추가

 

 

dw_1.insertrow(1)

로우 1번에 추가

 

 

dw_1.Insertrow(ll_row)

dw_1.Setfocus()

dw_1.Scrolltorow(ll_row)

dw_1.Setrow(ll_row)

 

 

**************************[dw 출력된값 배열에 넣기]**********************************************************************

※ 구조체나, datastore에 넣는게 더 좋을 것 같음

string ls_i[3,2], ls_text

long a = 0 , b = 0, c = 0, ll_start, ll_start2, d = 2

 

 

for ll_start = 1 to 3

 

 a+= 1

 

 

 for ll_start2 = 1 to 2

  

  b += 1

  

  ls_text = dw_campaign.GetItemString(a, d)  

  

  ls_i[a,b] = ls_text

  

  if d = 2 then

   d = 5

  else

   d = 2

  end if

 

 

 next

 b = 0

 

next

 

 

a = 0

b = 0

 

for ll_start = 1 to 3

 

 a+= 1

 

 

 

 for ll_start2 = 1 to 2

  

  b += 1

 

  messagebox("cirnform","ls_i["+string(a)+","+string(b)+"] = " + ls_i[a,b])

 

 

 next

 b = 0

 

next

 

 

 

 

 

 

**************************[itemchange이벤트와 itemfocuschange이벤트 설명]**********************************************************************

itemchange는 dw의 한 아이템값이 변경되었을 때 발생되는 것이고 ( 값 1-> 2)

 

 

itemfocuschange는 dw의 최초 retrieve 이후 로우수가 변경되는 것을 포함해

                   로우의 포커스가 변경될때 발생된다. ( 로우 1 - > 로우 2)

 

 

 

 

 

**************************[datastore로 dropdownlistbox or listbox안에 아이템 생성하기]**********************************************************************

ddlb_part

 

 

constructor

 

 

DataStore ldw

String  ls_sql, ls_error, ls_err, ls_deptcd

Long   ll_row, ll_i

 

 

ls_sql = " SELECT REFCD, SHORTNM FROM UDREFCD " + &

         " WHERE  REFSECT = 'X2'              " + &

   " AND    REFCD   <>   '000'          " + &

   " AND    REFCD   LIKE '_00'          " + &

     " ORDER BY DELYN ASC  "

 

 

ldw = CREATE DataStore

ldw.CREATE(SQLCA.SyntaxFromSQL(ls_sql, 'style=(FORM)', ls_error), ls_err)

ldw.SetTransObject(SQLCA)

ll_row = ldw.Retrieve()

 

 

IF ll_row < 1 THEN

 DESTROY ldw

 RETURN

END IF

 

 

ddlb_part.Reset()

FOR ll_i = 1 TO ll_row

 ls_deptcd = ldw.GetItemString(ll_i, 2) + space(20) + &

      ldw.GetItemString(ll_i, 1)

 ddlb_part.Additem(ls_deptcd)

NEXT

 

 

 

selectchanged

 

 

ddlb_circulsect.Reset()

ddlb_circulsect.Enabled = TRUE

pb_51.Enabled = True

wf_circulsect()

ddlb_circulsect.SelectItem(1)

cbx_circulsect.Checked = TRUE

cbx_dept.Checked = TRUE

 

 

 

 

 

wf_circulsect()

String  ls_sql, ls_err, ls_errcrt, ls_refcd, ls_shortnm

Int   li_i, li_j, li_len

 

 

DataStore ldw

ldw = CREATE Datastore

 

 

ls_sql = " SELECT REFCD, SHORTNM         " + &

         " FROM   UDREFCD                " + &

   " WHERE  REFSECT =        'X2'  " + &

   " AND    REFCD   NOT LIKE '_00' " + &   

   " AND    REFCD   LIKE '" + Mid(Right(ddlb_part.Text, 3), 1, 1) + "%'" + &

     " ORDER BY DELYN ASC   "

   

ldw.Create(SQLCA.SyntaxFromSQL(ls_sql, 'Style(Type=Form)', ls_err), ls_errcrt)

ldw.SetTransObject(SQLCA)

 

 

IF ldw.Retrieve() < 1 THEN

 DESTROY ldw

 RETURN

END IF

 

 

FOR li_j = 1 TO ldw.RowCount()

 ls_refcd   = Trim(ldw.Object.refcd[li_j])

 ls_shortnm = Trim(ldw.Object.SHORTNM  [li_j])    

 ddlb_circulsect.AddItem(ls_shortnm + SPACE(20) + ls_refcd)

NEXT

DESTROY ldw

 

 

ddlb_circulsect.SelectItem(0)

 

 

 

 

 

 

**************************[datawindow child로 검색조건 or 활용하기]**********************************************************************

**************************[dddw의 셋팅 스크립트]************************************************

window open event

dw_camp_lclss_id.SetTransObject(SQLCA)

dw_camp_lclss_id.InsertRow(0)

 

 

검색조건dw의 itemchange 이벤트

long ll_camp_lclss_id, ll_row

 

 

dw_camp_mclss_id.reset()

dw_camp_sclss_id.reset()

 

 

THIS.Accepttext()

 

 

ll_camp_lclss_id = THIS.GetItemNumber(row,"camp_lclss_id")

idw_child2.Retrieve (ll_camp_lclss_id)

 

 

ll_row = idw_child2.RowCount()

IF ll_row > 0 THEN dw_camp_mclss_id.InsertRow(0)

 

 

cb_sel.TriggerEvent(clicked!)

 

 

**************************[dddw의 filter]********************************************************************************************

idw_child4.SetFilter( " cd_val in ('10','20') ")

idw_child4.filter()

 

 

 

 

 

**************************[datawindow child로 검색조건 or 활용하기] * 복수개 로직************************************************

 

 

CHOOSE CASE dwo.name

 CASE 'classcd1'               // classcd1 클릭시 classcd2 에 대한 datawindowchild 함수 실행

 wf_classcd('classcd2', Left(data, 1) + '%', 2)

 

 

        as_colnm, as_classcd,             ai_levelorder

 

 

int    li_i,    li_row

string lsa1[5], lsa2[3]

datawindowchild ldwc

lsa1 = {'', 'classcd2',    'classcd3', 'classcd4', 'classcd5'}

lsa2 = {'', 'materialcd2', 'materialcd3'}

 

 

li_row = dw_2.GetRow()

 

 

dw_2.GetChild(as_colnm , ldwc)

ldwc.SetTransObject(SQLCA)

IF ai_levelorder = 1 THEN ldwc.Retrieve() &

                     ELSE ldwc.Retrieve(as_classcd, ai_levelorder)

dw_2.SetItem(li_row, as_colnm, '')

 

 

FOR li_i = ai_levelorder + 1 TO 5

 dw_2.GetChild(lsa1[li_i] , ldwc)

 ldwc.SetTransObject(SQLCA)

   ldwc.Reset()

   dw_2.SetItem(li_row, lsa1[li_i], '')

NEXT

 

 

**************************[dseq, 차순번 저장 로직]********************************************************************************************

dwItemStatus ldw_status

datetime  ldt_sysdate

long      ll_idx, ll_jdx, ll_camp_faq_id, ll_camp_faq_id_check, ll_camp_faq_sub_id, ll_camp_faq_sub_id_max

string    ls_camp_faq_sub_title

 

 

 

dw_detail.AcceptText()

 

 

IF dw_detail.ModifiedCount() = 0 AND dw_detail.deletedcount() = 0 THEN

    uo_msg.sle_msg.text = 'There are no changes.'

 return

END IF

 

 

select sysdate into :ldt_sysdate from dual;

 

 

FOR ll_idx = 1 TO dw_detail.rowcount()

 

 

  ldw_status = dw_detail.Getitemstatus(ll_idx, 0, Primary!)

 

 

  ll_camp_faq_id = dw_detail.GetItemNumber(ll_idx,"camp_faq_id")

 

 

  IF isnull(trim(string(ll_camp_faq_id))) or trim(string(ll_camp_faq_id)) = '' THEN

  

   Messagebox("Validation", "Please put the camp_faq_id!" )

   dw_detail.Setrow(ll_idx)

   dw_detail.Setcolumn("camp_faq_id")

   dw_detail.Setfocus()

    RETURN

    

  END IF

 

 

  ls_camp_faq_sub_title = dw_detail.GetItemString(ll_idx,"camp_faq_sub_title")

 

  IF isnull(trim(ls_camp_faq_sub_title)) or trim(ls_camp_faq_sub_title) = '' THEN

  

   Messagebox("Validation", "Please put the title!" )

   dw_detail.Setrow(ll_idx)

   dw_detail.Setcolumn("camp_faq_sub_title")

   dw_detail.Setfocus()

    RETURN

    

  END IF

 

 

  IF ldw_status = New! OR ldw_status = Newmodified!  THEN

   

   select nvl(max(camp_faq_sub_id),0)

   into   :ll_camp_faq_sub_id_max

   from   tb_ao113

   where  camp_faq_id = :ll_camp_faq_id;

   

   FOR ll_jdx = 1 TO dw_detail.rowcount()

 

              ll_camp_faq_id_check = dw_detail.GetItemNumber(ll_jdx,"camp_faq_id")

     ll_camp_faq_sub_id   = dw_detail.GetItemNumber(ll_jdx,"camp_faq_sub_id")

     

     IF ll_camp_faq_id = ll_camp_faq_id_check THEN

    

      IF ll_camp_faq_sub_id_max < ll_camp_faq_sub_id THEN

     

       ll_camp_faq_sub_id_max = ll_camp_faq_sub_id

      

      END IF

     

        END IF

   

    NEXT

    

   IF ll_camp_faq_sub_id_max = 0 THEN

   

    ll_camp_faq_sub_id_max = ll_camp_faq_id + 1

    

   ELSE

   

    ll_camp_faq_sub_id_max += 1

 

 

   END IF    

 

 

   dw_detail.object.camp_faq_sub_id [ll_idx] = ll_camp_faq_sub_id_max

   dw_detail.Object.etr_date    [ll_idx] = ldt_sysdate

   dw_detail.Object.etr_id       [ll_idx] = gstr_user_stat.user_id

   dw_detail.Object.mdf_date     [ll_idx] = ldt_sysdate

   dw_detail.Object.mdf_id      [ll_idx] = gstr_user_stat.user_id

   

   ll_camp_faq_sub_id_max = 0

   

 

 

    ELSEIF ldw_status = Datamodified! THEN

 

 

   dw_detail.Object.mdf_date     [ll_idx] = ldt_sysdate

   dw_detail.Object.mdf_id      [ll_idx] = gstr_user_stat.user_id

   

    END IF

 

 

NEXT

 

 

IF  dw_detail.Update() <> 1 THEN

    ROLLBACK ;

 MessageBox("Confirmation"," Save failed !!")

 RETURN

ELSE

    COMMIT;

    uo_msg.sle_msg.text = 'Save Success'

END IF

 

 

 

**************************[treeview 로직]********************************************************************************************

 

 

 

[tv_camp.clicked]

IF handle > 0 THEN

 

 

 il_handle = handle

 

 long   ll_rows, ll_camp_script_id

 treeviewitem ltvi_camp

 str_camp  lstr_str_camp

 

 

 GetItem( handle, ltvi_camp )

 

 lstr_str_camp = ltvi_camp.data

 

 ll_rows = dw_camp_dtl.Retrieve( lstr_str_camp.camp_script_id )

 

 IF ll_rows > 0 THEN

  dw_camp_dtl.Object.camp_script_title.TabSequence = 10

  dw_camp_dtl.Object.camp_script_context.TabSequence = 20

  dw_camp_dtl.Object.end_yn.TabSequence = 30

  dw_camp_dtl.Object.vl_yn.TabSequence = 40

 END IF

 

END IF

 

 

 

[tv_camp.constructor]

long  ll_row, i, ll_camp_script_id

String  ls_camp_script_title

 

 

TreeViewItem TvitemCon

str_camp    lstr_str_camp

Datastore  ds_data

 

 

ds_data = CREATE Datastore

ds_data.DataObject = "dw_camp_title"

ds_data.SetTransObject(SQLCA)

ll_row = ds_data.Retrieve()

 

 

FOR i = 1 TO ll_row

  

 lstr_str_camp.camp_script_id = ds_data.GetItemNumber(i,1)

 lstr_str_camp.camp_script_title = ds_data.GetItemString(i,2)

 

 TvitemCon.label = lstr_str_camp.camp_script_title

 TvitemCon.data  = lstr_str_camp

 /********************************************************/

 string ls_end_yn

 ll_camp_script_id = lstr_str_camp.camp_script_id

 

 select end_yn

 into :ls_end_yn

 from tb_ao111

 where camp_script_id = :ll_camp_script_id;

 

 if ls_end_yn = 'Y' then

  TvitemCon.children = false

 else  

  TvitemCon.children = true

 end if

 /********************************************************/

 //TvitemCon.children = TRUE

 TvitemCon.pictureindex = 1

 TvitemCon.selectedpictureindex = 2

 

 this.InsertItemLast(0,TvitemCon)

 

NEXT

 

 

DESTROY ds_data

 

 

 

 

 

[tv_camp.doubleclicked]

IF handle > 0 THEN

 

 

 il_handle = handle

 

 long   ll_rows, ll_camp_script_id

 treeviewitem ltvi_camp

 str_camp  lstr_str_camp

 

 

 GetItem( handle, ltvi_camp )

 

 lstr_str_camp = ltvi_camp.data

 

 ll_rows = dw_camp_dtl.Retrieve( lstr_str_camp.camp_script_id )

 

 IF ll_rows > 0 THEN

  dw_camp_dtl.Object.camp_script_title.TabSequence = 10

  dw_camp_dtl.Object.camp_script_context.TabSequence = 20

  dw_camp_dtl.Object.end_yn.TabSequence = 30

  dw_camp_dtl.Object.vl_yn.TabSequence = 40

 END IF

 

END IF

 

 

 

 

 

[tv_camp.itempopulate]

TreeViewItem  Tvitem_next, Tvitem_curr

long    i,ll_row, ll_level, ll_data, ll_camp_script_id, ll_camp_script_lvl, ll_last_item_cnt

str_camp  lstr_str_camp, lstr_str_curr

 

 

DataStore ds_data

 

 

IF GetItem(handle,Tvitem_curr) = -1 THEN RETURN

 

 

SetPointer(HourGlass!)

 

 

ll_level   = Tvitem_curr.level // node level

lstr_str_curr  = Tvitem_curr.data

 

 

ll_camp_script_id  = lstr_str_curr.camp_script_id

ll_camp_script_lvl = ll_level

 

 

ds_data = CREATE DataStore

ds_data.DataObject = "dw_camp_context"

ds_data.SetTransObject(SQLCA)

 

 

ll_row = ds_data.Retrieve(ll_camp_script_id, ll_camp_script_lvl + 1)

 

 

FOR i = 1 TO ll_row

 

 lstr_str_camp.camp_script_id   = ds_data.GetItemNumber(i,1)

 lstr_str_camp.camp_script_title  = ds_data.GetItemString(i,2)

 lstr_str_camp.camp_script_context  = ds_data.GetItemString(i,3)

 lstr_str_camp.camp_script_lvl   = ds_data.GetItemNumber(i,4)

 lstr_str_camp.up_camp_script_id  = ds_data.GetItemNumber(i,5)

 lstr_str_camp.end_yn     = ds_data.GetItemString(i,6)

 lstr_str_camp.vl_yn     = ds_data.GetItemString(i,7)

 

 Tvitem_next.label = lstr_str_camp.camp_script_title

 Tvitem_next.data  = lstr_str_camp

 

 

 

 long ll_lvl

 

 ll_lvl = lstr_str_camp.camp_script_lvl

 

 IF ll_lvl = 1                   THEN

  Tvitem_next.pictureindex = 1

     Tvitem_next.selectedpictureindex = 1

 

 ELSEIF ll_lvl = 2               THEN

  Tvitem_next.pictureindex = 2

     Tvitem_next.selectedpictureindex = 2

  

 ELSEIF ll_lvl = 3               THEN

  Tvitem_next.pictureindex = 3

     Tvitem_next.selectedpictureindex = 3

  

 ELSEIF ll_lvl = 4             THEN

  Tvitem_next.pictureindex = 4

     Tvitem_next.selectedpictureindex = 4

  

 ELSEIF ll_lvl = 5             THEN  

  Tvitem_next.pictureindex = 5

     Tvitem_next.selectedpictureindex = 5

  

 ELSEIF ll_lvl = 6             THEN

  Tvitem_next.pictureindex = 6

     Tvitem_next.selectedpictureindex = 6

 

 

 END IF

 

 IF lstr_str_camp.end_yn = 'Y' THEN

  Tvitem_next.children = FALSE   

 ELSE

  Tvitem_next.children = TRUE  

 END IF

 

 

 THIS.InsertItemLast(handle,Tvitem_next)

 

 

 

NEXT

 

 

DESTROY ds_data

 

 

 

 

 

 

 

 

 

 

 

[window.declare instance variables]

long il_handle

String is_first_yn = 'N'

 

 

 

 

 

 

[cb_first_ins]

long  ll_insert_row, ll_rtn, ll_level

 

 

dwItemStatus ldwis_status

 

 

ldwis_status = dw_camp_dtl.GetItemStatus( 1, 0, Primary! )

 

 

IF ldwis_status = DataModified! OR ldwis_status = NewModified! THEN

 ll_rtn = messagebox("Modified","There are changes you want to continue DATA ",Question!,YesNo!,2)

 

 

 IF ll_rtn = 2 THEN

  RETURN

 END IF

END IF

 

 

dw_camp_dtl.reset()

 

 

ll_insert_row = dw_camp_dtl.InsertRow(0)

 

 

IF ll_insert_row > 0 THEN

 

 il_handle = 0

 is_first_yn = 'Y'

 

 

 dw_camp_dtl.SetItem( ll_insert_row, "camp_script_id", 0 )

 dw_camp_dtl.SetItem( ll_insert_row, "up_camp_script_id", 0 )

 dw_camp_dtl.SetItem( ll_insert_row, "camp_script_lvl", 0 )    // First Insert level

 /******************************************************************************/

 dw_camp_dtl.SetItem( ll_insert_row, "end_yn", 'Y' )

 /******************************************************************************/

 dw_camp_dtl.SetItem( ll_insert_row, "vl_yn", 'Y' )

 dw_camp_dtl.SetItem( ll_insert_row, "etr_id", gstr_user_stat.user_id )

 dw_camp_dtl.SetItem( ll_insert_row, "etr_date", uf_sysdate() )

 dw_camp_dtl.SetItem( ll_insert_row, "mdf_id", gstr_user_stat.user_id )

 dw_camp_dtl.SetItem( ll_insert_row, "mdf_date", uf_sysdate() )

 

 dw_camp_dtl.Object.camp_script_title.TabSequence = 10

 dw_camp_dtl.Object.camp_script_context.TabSequence = 20

 dw_camp_dtl.Object.end_yn.TabSequence = 0

 dw_camp_dtl.Object.vl_yn.TabSequence = 0

 dw_camp_dtl.Setfocus()

 dw_camp_dtl.SetColumn("camp_script_title")

 

 dw_camp_dtl.SetItemStatus( 1, 0, Primary!, NotModified! )

 

 

END IF

 

 

 

 

 

[cb_ins]

long  ll_insert_row, ll_rtn, ll_level

 

 

dwItemStatus ldwis_status

 

 

ldwis_status = dw_camp_dtl.GetItemStatus( 1, 0, Primary! )

 

 

is_first_yn = "N"

 

 

IF ldwis_status = DataModified! OR ldwis_status = NewModified! THEN

 ll_rtn = messagebox("Modified","There are changes you want to continue DATA ",Question!,YesNo!,2)

 

 

 IF ll_rtn = 2 THEN

  RETURN

 END IF

END IF

 

 

dw_camp_dtl.reset()

 

 

ll_insert_row = dw_camp_dtl.InsertRow(0)

 

 

IF ll_insert_row > 0 THEN

 TreeViewItem  ltvi_curr

 str_camp  lstr_camp_curr

 

 

 IF tv_camp.GetItem( il_handle, ltvi_curr ) = -1 THEN

  dw_camp_dtl.Object.camp_script_title.TabSequence = 0

  dw_camp_dtl.Object.camp_script_context.TabSequence = 0

  Messagebox("Check", "Please select the top guide to type text!")

  RETURN

 END IF

 

 ll_level    = ltvi_curr.level

 lstr_camp_curr   = ltvi_curr.data  

 

 

 dw_camp_dtl.SetItem( ll_insert_row, "camp_script_id", 0 )

 dw_camp_dtl.SetItem( ll_insert_row, "up_camp_script_id", lstr_camp_curr.camp_script_id )

 dw_camp_dtl.SetItem( ll_insert_row, "camp_script_lvl", ll_level )

 /******************************************************************************/  

 dw_camp_dtl.SetItem( ll_insert_row, "end_yn", 'Y' )

 /******************************************************************************/  

 dw_camp_dtl.SetItem( ll_insert_row, "vl_yn", 'Y' )

 dw_camp_dtl.SetItem( ll_insert_row, "etr_id", gstr_user_stat.user_id )

 dw_camp_dtl.SetItem( ll_insert_row, "etr_date", uf_sysdate() )

 dw_camp_dtl.SetItem( ll_insert_row, "mdf_id", gstr_user_stat.user_id )

 dw_camp_dtl.SetItem( ll_insert_row, "mdf_date", uf_sysdate() )

 

 dw_camp_dtl.Object.camp_script_title.TabSequence = 10

 dw_camp_dtl.Object.camp_script_context.TabSequence = 20

 dw_camp_dtl.Object.end_yn.TabSequence = 0

 dw_camp_dtl.Object.vl_yn.TabSequence = 0

 dw_camp_dtl.Setfocus()

 dw_camp_dtl.SetColumn("camp_script_title")

 

 dw_camp_dtl.SetItemStatus( 1, 0, Primary!, NotModified! )

END IF

 

 

 

 

 

 

[cb_save]

long   ll_row_cnt, ll_camp_script_id, ll_level, ll_next_camp_script_id

DWItemStatus ldw_status

String   ls_camp_script_title, ls_end_yn, ls_vl_yn, ls_err_msg

 

 

TreeViewItem  ltvi_cur, ltvi_next

str_camp  lstr_camp_cur, lstr_camp_next

 

 

IF is_first_yn = "N" THEN

 

 

 IF tv_camp.GetItem( il_handle, ltvi_cur ) = -1 THEN

  dw_camp_dtl.Object.camp_script_title.TabSequence = 0

  dw_camp_dtl.Object.camp_script_context.TabSequence = 0

  RETURN

 END IF

 

 ll_level   = ltvi_cur.level

 lstr_camp_cur   = ltvi_cur.data

 

END IF

 

 

dw_camp_dtl.Accepttext()

 

 

ll_row_cnt = dw_camp_dtl.rowcount()

 

 

IF ll_row_cnt > 0 THEN

 ldw_status = dw_camp_dtl.getItemStatus( 1, 0, Primary! )

 

 IF ldw_status = New! OR ldw_status = NewModified! THEN

  

  lstr_camp_cur.camp_script_lvl = ll_level + 1

 

 

  ls_camp_script_title = trim(dw_camp_dtl.GetitemString( 1, "camp_script_title" ))

  

  IF isnull(ls_camp_script_title) OR ls_camp_script_title = "" THEN

   Messagebox("Validation", "Please camp_script_title!" )

 

   dw_camp_dtl.Setcolumn("camp_script_title")

   dw_camp_dtl.Setfocus()

   RETURN

  END IF

 

 

  ls_end_yn = dw_camp_dtl.GetitemString( 1, "end_yn" )

  

  IF isnull(ls_end_yn) OR ls_end_yn = "" THEN

   Messagebox("Validation", "Please end_yn!" )

 

   dw_camp_dtl.Setcolumn("end_yn")

   dw_camp_dtl.Setfocus()

   RETURN

  END IF

  

  ls_vl_yn = dw_camp_dtl.GetitemString( 1, "vl_yn" )

  

  IF isnull(ls_vl_yn) OR ls_vl_yn = "" THEN

   Messagebox("Validation", "Please vl_yn!" )

 

   dw_camp_dtl.Setcolumn("vl_yn")

   dw_camp_dtl.Setfocus()

   RETURN

  END IF

 

 

  SELECT SQ_CAMP_SCRIPT_ID.NEXTVAL

    INTO :ll_next_camp_script_id

    FROM DUAL       ;

  

  dw_camp_dtl.setItem( 1, "camp_script_id", ll_next_camp_script_id )

  dw_camp_dtl.setItem( 1, "up_camp_script_id", lstr_camp_cur.camp_script_id )

  dw_camp_dtl.setItem( 1, "camp_script_lvl", lstr_camp_cur.camp_script_lvl )

  dw_camp_dtl.setItem( 1, "etr_id", gstr_user_stat.user_id )

  dw_camp_dtl.setItem( 1, "etr_date", uf_sysdate() )

  dw_camp_dtl.setItem( 1, "mdf_id", gstr_user_stat.user_id )

  dw_camp_dtl.setItem( 1, "mdf_date", uf_sysdate() )

  

     /******************************************************************************/  

  long ll_up_camp_script_id

  ll_up_camp_script_id = dw_camp_dtl.GetItemNumber(1,"up_camp_script_id")

  

  update tb_ao111

  set end_yn ='N'

  where camp_script_id = :ll_up_camp_script_id;

     /******************************************************************************/  

 

 ELSEIF ldw_status = DataModified! THEN

 

 

  dw_camp_dtl.setItem( 1, "mdf_id", gstr_user_stat.user_id )

  dw_camp_dtl.setItem( 1, "mdf_date", uf_sysdate() )

  

  lstr_camp_cur.camp_script_title = dw_camp_dtl.GetItemString( 1, "camp_script_title" )

  lstr_camp_cur.camp_script_id  = dw_camp_dtl.GetItemNumber( 1, "camp_script_id" )

  

  ltvi_cur.label = lstr_camp_cur.camp_script_title

  ltvi_cur.data  = lstr_camp_cur

  

  tv_camp.SetItem( il_handle, ltvi_cur )

 END IF

 

ELSE

 RETURN

END IF

 

 

dw_camp_dtl.Accepttext()

 

 

IF dw_camp_dtl.UPDATE() = 1 THEN

 

 

 COMMIT;

 

 

 IF ldw_status = NewModified! THEN

  

  IF is_first_yn = "Y" THEN

   tv_camp.deleteItem(0)

   tv_camp.TriggerEvent(constructor!)

  END IF

  

  IF ltvi_cur.children = TRUE THEN

   

   lstr_camp_next.camp_script_id    = ll_next_camp_script_id

   lstr_camp_next.camp_script_title    = dw_camp_dtl.getItemString( 1, "camp_script_title" )

   lstr_camp_next.camp_script_context  = dw_camp_dtl.getItemString( 1, "camp_script_context" )

   lstr_camp_next.up_camp_script_id   = lstr_camp_cur.camp_script_id

   lstr_camp_next.camp_script_lvl   = lstr_camp_cur.camp_script_lvl

   lstr_camp_next.end_yn      = "N"

   lstr_camp_next.vl_yn      = "Y"

      

   ltvi_next.label = lstr_camp_next.camp_script_title

   ltvi_next.data  = lstr_camp_next

   

   ltvi_next.children = FALSE

   

   ltvi_next.pictureindex = 1

   ltvi_next.selectedpictureindex = 2

   

   /**********************************************************************/

   //delete -> reset

   //long ll_ins_handle

   //ll_ins_handle = tv_camp.InsertItemLast( il_handle, ltvi_next )

   //tv_camp.deleteItem(0)

   //tv_camp.TriggerEvent(constructor!)

   //tv_camp.setfocus()

   //tv_camp.selectitem( ll_ins_handle )

   

   tv_camp.InsertItemLast( il_handle, ltvi_next )

   tv_camp.expandItem( il_handle )

     

  ELSE

   ltvi_cur.children = TRUE

   tv_camp.setItem( il_handle, ltvi_cur )

   tv_camp.expandItem( il_handle )

  END IF

  

 END IF

 

 

ELSE

 

 ls_err_msg = sqlca.sqlerrtext

 

 

 Messagebox("Error", "INSERT & UPDATE Error!  " + ls_err_msg )

 ROLLBACK;

 RETURN

 

 

END IF

 

 

is_first_yn = "N"

 

 

 

[treeview 전부 펼치기, 전부 닫기, 검색 열기]

 

 

전부 펼치기

 

 

integer i, itot

 

 

itot = wf_totalitem(tv_camp)

 

 

for i = 1 to itot

 tv_camp.ExpandAll(i)

next

 

 

 

전부 닫기

 

 

integer i, itot

 

 

itot = wf_totalitem(tv_camp)

 

for i = 1 to itot

 tv_camp.CollapseItem(i)

next

 

 

 

[wf_totalitem]

//long of_TotalItems(treeview atv)

long   li_handle, i_h

TreeViewItem  ltvi_Emp

 

 

if Not IsValid( atv ) then return -1

 

 

TRY

 li_handle = atv.FindItem(RootTreeItem!, il_handle)

 i_h = atv.GetItem(li_handle, ltvi_Emp)

 if i_h < 0 then return 0

 

 DO WHILE i_h > 0

  li_handle++

  i_h = atv.GetItem(li_handle, ltvi_Emp)

  Yield()

 Loop

 i_h = li_handle - 1

 

 

CATCH (RunTimeError Err)

 i_h = -1

END TRY

 

 

return i_h

 

 

 

 

 

검색 열기

 

 

String ls_sle, ls_camp_script_title

long ll_handle, ll_min_camp_script_id

 

 

ls_sle = trim(sle_1.text)

 

 

IF isnull(ls_sle) OR ls_sle = '' THEN

 Messagebox("Valid", "Please Enter title!")

 sle_1.Setfocus()

 RETURN

END IF

 

 

select nvl(min( camp_script_id ), 0)

  into :ll_min_camp_script_id

  from tb_ao111

 where camp_script_title like '%'||:ls_sle||'%' ;

 

IF ll_min_camp_script_id > 0 THEN

 

 select camp_script_title

   into :ls_camp_script_title

   from tb_ao111

  where camp_script_id = :ll_min_camp_script_id ;

  

 ll_handle = wf_findvhandle( tv_camp, ls_camp_script_title, 'label' )

 

 

 tv_camp.SelectItem(ll_handle)

 

 

ELSE

 

 Messagebox("Valid", "No Data!")

 RETURN

 

 

END IF

 

 

 

 

 

[wf_findvhandle]

// TreeView에서 값을 가지고 핸들값을 찾는다.

// integer of_findtvhandle ( atv, as_data, as_find )

Integer iHandle, i_rtn = 1

integer li_handle, i_h

TreeViewItem ltvi_Emp

String ls_data

 

 

if Not IsValid(tv_camp) then i_rtn = -1

 

 

if i_rtn > 0 then

 li_handle = tv_camp.FindItem(RootTreeItem!, 0)

 i_h = tv_camp.GetItem(li_handle, ltvi_Emp)

 if i_h < 0 then i_rtn = -1

end if

 

 

if i_rtn > 0 then

 DO WHILE i_h > 0

  li_handle++

  i_h = tv_camp.GetItem(li_handle, ltvi_Emp)

  Yield()

  if Upper(as_find) = 'DATA' then

   if ltvi_Emp.data = as_data then

    iHandle = li_handle

    exit

   end if

  else

   if ltvi_Emp.label = as_data then

    iHandle = li_handle

    exit

   end if

  end if

 Loop

end if

if i_rtn > 0 then

 i_rtn = iHandle

end if

 

 

return i_rtn

 

 

 

[하위 Treeview 모두 펼치기]

// 하위의 모든 Tree를 펼친다.

// integer gf_TreeViewAllExpend ( atv, ai_total )

Integer i_Index

For i_Index = ai_start to ai_total

 atv.ExpandItem(i_Index)

next

return gf_TreeViewTotaItems(atv)

 

 

 

 

 

 

 

 

 

[Treeview 하위 부서 가져오기]

//tv_team.doubleclicked

 

 

long            ll_row,    ll_team_lvl, ll_disp_seq,   ll_idx,    ll_handle

string          ls_team_id, ls_sql,   ls_team_list,  ls_data[]

treeview        ltvi_team

str_team_id     lstr_str_team

 

 

dw_user.SetTransObject(sqlca)

dw_user.Reset()

 

 

IF handle > 0 THEN

 

 il_handle = handle

 

 

 ll_handle = tv_team.FindItem(CurrentTreeItem!, 0)

 If ll_handle <= 0 Then  Return

 

 wf_tv_Get_Child_Data ( tv_team , ll_handle , ls_data[] )

 FOR ll_idx=1 To Upperbound(ls_data[])

  

  IF ll_idx = Upperbound(ls_data[]) THEN

   ls_team_list += "'"+ls_data[ll_idx]+"'"

  ELSE

   ls_team_list += "'"+ls_data[ll_idx]+"'"+', '

  END IF

 NEXT

 

 ls_sql = dw_user.GetSQLSelect()

 

 

 ls_sql  = ""+&

     " SELECT TEAM_ID  TEAM_ID,              " + &

     "        USER_ID  USER_ID,              " + &

     "        EMP_NM   EMP_NM,               " + &

     "        'N'      CHK                   " + &

     " FROM   TB_ZZ031  ZZ031                " + &

     " WHERE  TEAM_ID IN ("+ls_team_list+")  "

 

 

 dw_user.SetSQLSelect(ls_sql)

 dw_user.Retrieve()

 dw_user.Setfocus()

 

END IF

 

 

// wf_tv_Get_Child_Data ( atv , al_ParentHandle , rf_s_Data[] )

// RETURN : (none)

 

 

TreeViewItem ltvi_Emp

Long         ll_handle

str_team_id  lstr_str_team

 

 

If Upperbound(rf_s_Data[])=0 Then

 atv.GetItem(al_ParentHandle, ltvi_Emp)

 

 lstr_str_team = ltvi_Emp.data

 

// rf_s_Data[ Upperbound(rf_s_Data[]) + 1 ] = String(ltvi_Emp.Data)

 rf_s_Data[ Upperbound(rf_s_Data[]) + 1 ] = lstr_str_team.team_id

 

End If

 

 

ll_handle = atv.FindItem(ChildTreeItem!, al_ParentHandle)

 

 

Do While ll_handle<>-1

 atv.GetItem(ll_handle, ltvi_Emp)

 

 

 lstr_str_team = ltvi_Emp.data

 

// rf_s_Data[ Upperbound(rf_s_Data[]) + 1 ] = String(ltvi_Emp.Data)

 rf_s_Data[ Upperbound(rf_s_Data[]) + 1 ] = lstr_str_team.team_id

 

 wf_tv_Get_Child_Data( atv , ll_handle, rf_s_Data[] )

 

 ll_handle = atv.FindItem(NextTreeItem!, ll_handle)

 

Loop

 

 

 

 

 

[Treeview에서 disp_seq 변경하고 나서 저장하는 로직 및 펑션]

// disp_seq set button click event

long   ll_disp_seq, ll_handle

boolean   lb_more_data

str_team_id  lstr_item_team

treeviewitem ltvi_user, ltvi_team

 

 

ll_disp_seq = 0

 

 

tv_team.setRedraw( False )

 

 

ll_handle = tv_team.FindItem( RootTreeItem!, ll_handle )

 

 

tv_team.expandAll( ll_handle )

 

 

IF ll_handle > 0 THEN

 lb_more_data = true

ELSE

 lb_more_data = false

END IF

 

 

DO WHILE lb_more_data

 

 

 tv_team.getItem( ll_handle, ltvi_team )

 lstr_item_team = ltvi_team.data

 

 wf_set_seq( ll_handle, ll_disp_seq, tv_team )

 

 ll_handle = tv_team.FindItem( NextTreeItem!, ll_handle )

 

 IF ll_handle >= 0 THEN

  lb_more_data = true

 ELSE

  lb_more_data = false

 END IF

 

LOOP

 

 

long tvi_hdl = 0

 

 

DO UNTIL tv_team.FindItem(RootTreeItem!, 0) = -1

    tv_team.DeleteItem(tvi_hdl)

LOOP

 

 

tv_team.setRedraw( True )

 

 

tv_team.postevent('constructor')

 

 

 

 

 

 

// wf_set_seq

 

 

 

long   ll_child_handle

boolean   lb_more_data

treeviewitem ltvi_team

str_team_id  lstr_item_team

 

 

ll_child_handle = atv_team.FindItem( ChildTreeItem!, al_handle )

 

 

IF ll_child_handle > 0 THEN

 lb_more_data = true

ELSE

 lb_more_data = false

END IF

 

 

DO WHILE lb_more_data

 

 

 tv_team.getItem( ll_child_handle, ltvi_team )

 lstr_item_team = ltvi_team.data

 

 al_disp_seq = al_disp_seq + 1

 

 UPDATE tb_zz021

 SET    disp_seq = :al_disp_seq

 WHERE  team_id  = :lstr_item_team.team_id;

 

 COMMIT;

 

 wf_set_seq( ll_child_handle, al_disp_seq, atv_team )

 

 ll_child_handle = tv_team.FindItem( NextTreeItem!, ll_child_handle )

 

 IF ll_child_handle >= 0 THEN

  lb_more_data = true

 ELSE

  lb_more_data = false

 END IF

 

LOOP

 

 

return 0

 

 

 

***********[itemchange에서 해당값의 중복값 찾아서 해당값 없애기 자삭, itemchange, itemfocuschange, rowfocuschange관계]*********************************

 

 

(itemchange)

String ls_cust_id, ls_cust_id2

Long   ll_camp_id, ll_camp_id2, ll_cnt, ll_row, ll_idx

 

 

THIS.ACCEPTTEXT()

 

 

ll_row = THIS.RowCount()

 

 

CHOOSE CASE dwo.name

 CASE 'cust_id'

  

  ll_camp_id = THIS.GetItemNumber(ROW,'camp_id')

  ls_cust_id = DATA

  

  SELECT NVL(COUNT(*),0) - 1

  INTO   :ll_cnt

  FROM   TB_AO202

  WHERE  CUST_ID = :ls_cust_id

  AND    CAMP_ID = :ll_camp_id;

  

  FOR ll_idx = 1 TO ll_row

   ls_cust_id2 = THIS.GetItemString(ll_idx,'cust_id')

   ll_camp_id2 = THIS.GetItemNumber(ll_idx,'camp_id')

   IF ls_cust_id = ls_cust_id2 AND ll_camp_id = ll_camp_id2 THEN

    ll_cnt += 1

   END IF   

  NEXT

  

  IF ll_cnt > 0 THEN

   MESSAGEBOX("Confirmation","Duplicated customer ID!")

   This.PostEvent('ue_event')   OR This.Post SetItem(row, "cust_id", '')

  END IF

  

END CHOOSE

 

 

 

(ue_event)

long i

String ls_cust_id

 

 

THIS.ACCEPTTEXT()

 

 

i = THIS.GetRow()

ls_cust_id = ''

 

 

THIS.SetItem(i, "cust_id", ls_cust_id)

 

 

 

 

 

(itemfocuschange)

il_row = row

 

 

 

 

 

 

(rowfocuschange)

String ls_cust_id, ls_cust_id2

Long   ll_camp_id, ll_camp_id2, ll_cnt, ll_row, ll_idx

 

 

THIS.ACCEPTTEXT()

 

 

ll_row = THIS.RowCount()

 

 

ll_camp_id = THIS.GetItemNumber(il_row,'camp_id')

ls_cust_id = THIS.GetItemString(il_row,'cust_id')

 

 

SELECT NVL(COUNT(*),0) - 1

INTO   :ll_cnt

FROM   TB_AO202

WHERE  CUST_ID = :ls_cust_id

AND    CAMP_ID = :ll_camp_id;

 

 

FOR ll_idx = 1 TO ll_row

 ls_cust_id2 = THIS.GetItemString(ll_idx,'cust_id')

 ll_camp_id2 = THIS.GetItemNumber(ll_idx,'camp_id')

 IF ls_cust_id = ls_cust_id2 AND ll_camp_id = ll_camp_id2 THEN

  ll_cnt += 1

 END IF

NEXT

 

 

IF ll_cnt > 0 THEN

 THIS.SetItem(il_row, "cust_id", '')

END IF

 

 

 

 

 

 

***********[dw 컬럼 두번 클릭시 sort]***************************************************************************************************

IF row < 1 THEN

 ls_old_column = is_old_column

 

 ls_title = this.getobjectatpointer()

 

 IF ii_sort = 0 then

  ii_sort = 1

 ELSE

  ii_sort = 0

 END IF

 

 is_old_column = uf_sort( this, ls_old_column, ii_sort, ls_title )

 this.SetRow( 1 )

 

 return

 

END IF

 

 

***********[tabpage간 이동]***************************************************************************************************

tab_1.selectedtab = 1

 

 

 

***********[DW 1번에서 저장한 내용 DW 2번에서 선택된 DDW에 해당되는 컬럼에 아규멘트가 없어도 출력하는 방법]*******************************************************

window open event에서

dw_detail.GetChild        ("camp_faq_id",   idw_child5)

idw_child5.SetTransObject(SQLCA)

 

 

저장버튼에다가

idw_child5.retrieve()

 

 

 

*************[dw 생성시 컬럼명 앞에 테이블명 앞에 안나오게 하는 방법]*******************************************************************************

select a.camp, b.camp_seq

 

 

   from a1 a,

 

 

           (select * from b1) b

 

 

 where a.camp = b.camp

 

 

 

 

만든뒤에

 

 

다시

 

 

select a.camp, b.camp_seq

 

 

   from a1 a,

 

 

           b1 b

 

 

 where a.camp = b.camp

 

 

 

 

 

로 다시 치환하면 됨

 

 

 

*************[부서명 가져오는 DB펑션]**********************************************************************************************************

CREATE OR REPLACE Function SHOP88.sf_get_team_id (

   as_team_id   IN    TB_ZZ021.team_id%type

                                                                  )

   return             varchar2                                                                  

IS

   ls_team_id           TB_ZZ021.team_id%type;

   ls_team_id_sum    varchar2(500) := '';

    ll_row_cnt      number(3)  := 0;   

 

 

   CURSOR csr_team IS

   

       SELECT TEAM_ID

        FROM   TB_ZZ021

        WHERE  UP_TEAM_ID =  as_team_id

        ORDER BY DISP_SEQ;

 

 

BEGIN

 

 

  OPEN  csr_team;

 

 

  FETCH  csr_team

  INTO  ls_team_id;

 

 

  LOOP

 

 

    EXIT WHEN  csr_team%NOTFOUND;

 

 

          ll_row_cnt := ll_row_cnt + 1;

 

 

         IF ll_row_cnt = 1 THEN

             ls_team_id_sum := ls_team_id;

         ELSE

             ls_team_id_sum := ls_team_id_sum || ' ,  ' ||ls_team_id;

         END IF;

 

 

          FETCH  csr_team

           INTO  ls_team_id;

 

 

   END LOOP;

 

 

  IF ll_row_cnt = 0  THEN

     return  '';

  ELSE

     return  ls_team_id_sum;

  END IF;

 

 

EXCEPTION

  WHEN no_data_found THEN  return 'no_data_found';

  WHEN others        THEN  return to_char(sqlcode);

 

 

END sf_get_team_id;

/

 

 

 

 

 

*******************중복 데이터 find 스크립트 **********************************************************************☆

long   ll_idx,       ll_fullrow,        ll_useday_cnt,   &

          ll_cnt

long   ll_find,     ll_find_1,         ll_find_2,        &

          ll_dup_cnt,      ll_dup_src_cust_id, ll_dup_src_cust_ssn,  &

    ll_dup_tel_home, ll_dup_tel_mobile

String    ls_src_cust_id,  ls_src_cust_ssn,    ls_src_cust_nm,   &

          ls_tel_home,     ls_tel_mobile,      ls_msg_box

dwitemstatus ldw_status

 

 

uo_msg.sle_msg.text = ''

 

 

dw_src_cust.AcceptText()

ll_fullrow = dw_src_cust.Rowcount()

 

 

IF ll_fullrow < 1 THEN RETURN

 

 

dw_src_cust.SetRedraw(FALSE)

dw_src_cust.SelectRow(0, FALSE)

 

 

FOR ll_idx = 1 TO ll_fullrow

 dw_src_cust.SetItem(ll_idx,'chk','N')

NEXT

 

 

//* Check of duplicate in datawindow *//

FOR ll_idx = 1 TO ll_fullrow

 

 ls_src_cust_id  = dw_src_cust.GetItemString(ll_idx,'src_cust_id')

 ls_src_cust_nm  = dw_src_cust.GetItemString(ll_idx,'src_cust_nm')

 ls_src_cust_ssn = dw_src_cust.GetItemString(ll_idx,'src_cust_ssn')

 ls_tel_home     = dw_src_cust.GetItemString(ll_idx,'tel_home')

 ls_tel_mobile   = dw_src_cust.GetItemString(ll_idx,'tel_mobile')

 

 //* Check of src_cust_id for duplicate in datawindow *//

 IF ls_src_cust_id = '0' OR IsNull(ls_src_cust_id) THEN

 ELSE

  IF ll_idx <> ll_fullrow THEN

   ll_find = dw_src_cust.Find("src_cust_id = '" + ls_src_cust_id+"'", 1+ll_idx, ll_fullrow)

  ELSE

   ll_find = 0

  END IF  

 END IF

 

 IF ll_find > 0 THEN

 

 

  IF NOT dw_src_cust.GetItemString(ll_idx, 'chk') = 'Y' THEN

   dw_src_cust.SetItem(ll_idx, 'color', 'i')

   dw_src_cust.SetItem(ll_idx, 'chk', 'Y')

   ll_dup_cnt += 1

   ll_dup_src_cust_id = ll_dup_src_cust_id + 1

  END IF

  

  IF NOT dw_src_cust.GetItemString(ll_find, 'chk') = 'Y' THEN

   dw_src_cust.SetItem(ll_find, 'color', 'i')

   dw_src_cust.SetItem(ll_find, 'chk', 'Y')

   ll_dup_cnt += 1

   ll_dup_src_cust_id = ll_dup_src_cust_id + 1

  END IF   

  

 END IF

 

 ll_find = 0

 

 //* Check of src_cust_ssn for duplicate in datawindow *//

 IF ls_src_cust_ssn = '0' OR IsNull(ls_src_cust_ssn) THEN

 ELSE

  IF ll_idx <> ll_fullrow THEN

   ll_find = dw_src_cust.Find("src_cust_ssn = '" + ls_src_cust_ssn+"'", 1+ll_idx, ll_fullrow)

  ELSE

   ll_find = 0

  END IF

 END IF

 

 IF ll_find > 0 THEN

 

 

  IF NOT dw_src_cust.GetItemString(ll_idx, 'chk') = 'Y' THEN

   dw_src_cust.SetItem(ll_idx, 'color', 's')

   dw_src_cust.SetItem(ll_idx, 'chk', 'Y')

   ll_dup_cnt += 1

   ll_dup_src_cust_ssn = ll_dup_src_cust_ssn + 1

  END IF

  

  IF NOT dw_src_cust.GetItemString(ll_find, 'chk') = 'Y' THEN

   dw_src_cust.SetItem(ll_find, 'color', 's')

   dw_src_cust.SetItem(ll_find, 'chk', 'Y')

   ll_dup_cnt += 1

   ll_dup_src_cust_ssn = ll_dup_src_cust_ssn + 1

  END IF   

  

 END IF  

 

 ll_find = 0

 

 //* Check of src_cust_nm, tel_mobile for duplicate in datawindow *//

 IF (ls_src_cust_nm = '0' OR IsNull(ls_src_cust_nm)) OR &

  (ls_tel_mobile = '0' OR IsNull(ls_tel_mobile)) THEN

 ELSE

  IF ll_idx <> ll_fullrow THEN

   ll_find = dw_src_cust.Find("src_cust_nm = '" + ls_src_cust_nm+"' and " + &

                              "tel_mobile  = '" + ls_tel_mobile+"'", 1+ll_idx, ll_fullrow)

  ELSE

   ll_find = 0

  END IF  

 END IF

 

 IF ll_find > 0 THEN

  

  IF NOT dw_src_cust.GetItemString(ll_idx, 'chk') = 'Y' THEN

   dw_src_cust.SetItem(ll_idx, 'color', 'm')

   dw_src_cust.SetItem(ll_idx, 'chk', 'Y')

   ll_dup_cnt += 1

   ll_dup_tel_mobile = ll_dup_tel_mobile + 1

  END IF

  

  IF NOT dw_src_cust.GetItemString(ll_find, 'chk') = 'Y' THEN

   dw_src_cust.SetItem(ll_find, 'color', 'm')

   dw_src_cust.SetItem(ll_find, 'chk', 'Y')

   ll_dup_cnt += 1

   ll_dup_tel_mobile = ll_dup_tel_mobile + 1

  END IF  

 

 

 END IF

 

 ll_find = 0

 

 //* Check of src_cust_nm, tel_home for duplicate in datawindow *//

 IF (ls_src_cust_nm = '0' OR IsNull(ls_src_cust_nm)) OR &

  (ls_tel_home = '0' OR IsNull(ls_tel_home)) THEN

 ELSE

  IF ll_idx <> ll_fullrow THEN

   ll_find = dw_src_cust.Find("src_cust_nm = '" + ls_src_cust_nm+"' and " + &

                              "tel_home    = '" + ls_tel_home+"'" , 1+ll_idx, ll_fullrow)

  ELSE

   ll_find = 0

  END IF  

 END IF

 

 IF ll_find > 0 THEN

  

  IF NOT dw_src_cust.GetItemString(ll_idx, 'chk') = 'Y' THEN

   dw_src_cust.SetItem(ll_idx, 'color', 'h')

   dw_src_cust.SetItem(ll_idx, 'chk', 'Y')

   ll_dup_cnt += 1

   ll_dup_tel_home = ll_dup_tel_home + 1

  END IF

  

  IF NOT dw_src_cust.GetItemString(ll_find, 'chk') = 'Y' THEN

   dw_src_cust.SetItem(ll_find, 'color', 'h')

   dw_src_cust.SetItem(ll_find, 'chk', 'Y')

   ll_dup_cnt += 1

   ll_dup_tel_home = ll_dup_tel_home + 1

  END IF

 

 

 END IF

 

 ll_find = 0

 

NEXT

 

IF ll_dup_cnt > 0 THEN

 ls_msg_box = " Save failed!"

 

 IF ll_dup_src_cust_id > 0 THEN

  ls_msg_box += " ~n Duplicated src_cust_id count : "+string(ll_dup_src_cust_id)

 END IF

 IF ll_dup_src_cust_ssn > 0 THEN

  ls_msg_box += " ~n Duplicated src_cust_ssn count : "+string(ll_dup_src_cust_ssn)

 END IF

 IF ll_dup_tel_home > 0 THEN

  ls_msg_box += " ~n Duplicated src_cust_nm & tel_home count : "+string(ll_dup_tel_home)

 END IF

 IF ll_dup_tel_mobile > 0 THEN

  ls_msg_box += " ~n Duplicated src_cust_nm & tel_mobile count : "+string(ll_dup_tel_mobile)

 END IF

 dw_src_cust.SetRedraw(TRUE)

 MESSAGEBOX("Confirmation", ls_msg_box)

 is_find = 'Y'

 dw_src_cust.SetSort("color")

 dw_src_cust.Sort()

 dw_src_cust.Scrolltorow(ll_fullrow)

 cb_delete.Enabled = TRUE

 cb_update.Enabled = FALSE

 tab_1.TriggerEvent('ue_insert')

 RETURN

END IF

 

is_find = 'N'

uo_msg.uf_msg("Duplicated customer were unable to find.")

 

 

dw_src_cust.SetRedraw(TRUE)

 

 

 

 

 

*************************[dw윈도우 컬럼명 클릭시 해당 컬럼대로 sort 출력하는 펑션 및 이벤트 스크립트]*********************************************

 

 

 

[doubleclick이벤트 ]

 

 

String  ls_title, ls_old_column

 

 

IF row < 1 THEN

 

 ls_old_column = is_old_column

 ls_title = THIS.getobjectatpointer()

   

 IF ii_sort = 0 then

  ii_sort = 1

 ELSE

  ii_sort = 0

 END IF

 

 is_old_column = uf_sort( THIS, ls_old_column, ii_sort, ls_title )

 

[[[[[[uf_sort]]]]]]]

long   ll_pos

string ls_sort, ls_col, ls_color

statictext  ls_text

 

 

ll_pos = pos( as_title, "_t~t" )

 

 

IF ll_pos > 0 THEN

 

 ls_sort = left( as_title, ll_pos - 1 )

 

 ls_col = ls_sort + "_t"

 

 IF ai_sort = 0 then

  ls_sort += " D"

 ELSE

  ls_sort += " A"

 END IF

 

 adw_datawindow.setsort(ls_sort)

 adw_datawindow.sort()

 

 adw_datawindow.Modify( as_old_column+".Color =65536 * 192 + 256 * 192 + 192" )

 

 ls_color = String(255* ( 1 - ai_sort ) +  65536 * 255 * ai_sort )

 adw_datawindow.Modify( ls_col+".Color =" + ls_color )

 

END IF

 

 

return ls_col

]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

 

 

 

 

 

 THIS.selectrow(0,FALSE)

 RETURN

end if

 

 

 

 

 

************************************************[구조체 변수 받아 팝업화면 열고 닫기open, close]*********************************************

OpenWithParm(w_ao114_01, lstr_camp_board)

 

 

CloseWithReturn(Parent, lstr_camp_board)

 

 

 

 

 

 

 

********************************************************************[함수총정리]*************************************************************************

1. 배열(Array)처리 함수  

LowerBound : 지정한 배열의 하위 경계

UpperBound : 지정한 배열의 상위 경계

2. Bolb관련 함수  

Blob      : 텍스트 데이터를 Blob 데이터로 변환 또는 복사

BlobEdit  : PB가 지원하는 데이터를 Blob변수로 복사

BlobMid    : Blob 데이터 문자열에서 N번째 문자를 반환

Len        : 문자열의 길이

3. 데이터형 검사 및 변환 함수  

Char      : blob,정수,문자열을 문자로 바꿔서 반환

Dec        : 문자열의 내용을 십진수로 바꿔서 반환

Double    : 문자열의 내용을 Double로 바꿔서 반환

Integer    : 문자열의 내용을 정수로 바꿔서 반환

Long      : 문자열의 내용을 long으로 바꿔서 반환

Real      : 문자열의 내용을 실수로 바꿔서 반환

Date      : 데이터베이스로부터 읽은 DateTime값에서 Date부분만 빼온다.

DateTime  : Date나 Time을 DateTime 값으로 변환한다.

IsDate    : 지정한 문자열이 유효한 Date값을 지녔는지 검사한다.  

IsNull    : 넘어온 인자가 NULL인지 검사한다.

IsNumber  : 지정한 문자열이 숫자값을 지녔는지 검사한다.

IsTime    : 지정한 문자열이 유효한 Time값을 지녔는지 검사한다.

String    : 지정한 형식으로 문자열을 얻는다.

Time      : 데이터베이스로부터 읽은 DateTime값에서 Time부분만 빼온다.

4. 날짜,요일,시간 처리 함수  

Day        : 일자를 구한다(1에서 31 사이의 정수)

DayName    : 주간의 요일명을 구한다.

DayNumber  : 주간의 요일을 숫자로 표현한다.(예를들면 일요일은1, 목요일은 5)

DaysAfter  : 지정한 날짜에 n일전,후를 구한다.

Hour      : 주어진 시간의 시 값을 구한다.

Minute    : 주어진 시간의 분 값을 구한다.

Month      : 주어진 날짜의 월 값을 구한다.(1에서 12까지)

Now        : 클라이언트의 시스템 시간을 구한다.

RelativeDate:주어진 날짜를 기준으로 n일 후 날짜를 구한다.

RelativeTime:주어진 시간을 기준으로 n초 후 시간을 구한다.

Second    : 주어진 시간의 초 값을 구한다.

Today      : 클라이언트의 현재 날짜를 구한다.

Year      : 주어진 날짜의 년 값을 구한다.(1000에서 3000년까지임)

5.DDE클라이언트 함수  

CloseChannel:OpenChannel함수로 열린 DDE서버 어플리케이션의 채널을 닫는다.

ExecRemote : 서버 어플리케이션에게 명령 실행을 요구한다.

GetDataDDE : 연결된 서버 어플리케이션으로부터 새로운 데이터를 받아온다.

GetDataDDEOrigin:연결된 서버 어플리케이션으로부터 원래의 데이터를 받아온다.

GetRemote  : 서버 어플리케이션에게 데이터를 요구한다.

OpenChannel: DDE서버 어플리케이션을 연다.

RespondRemote:서버에게 명령 또는 데이터가 클라이언트에게 받아들여졌는지를 알려준

다.

SetRemote  : 서버 어플리케이션에게 지정한 값을 설정하도록 한다.

StartHotLink:서버 어플리케이션과의 연결을 시작한다.

StopHotLink: 서버 어플리케이션과의 연결을 종료한다.

6. DDE서버 함수  

GetCommandDDE: 클라이언트 어플리케이션이 보낸 명령을 구한다.

GetCommandDDEOrigin:어떤 클라이언트 어플리케이션이 명령을 보냈는지 구한다.

GetDataDDE : 클라이언트 어플리케이션이 보낸 데이터를 구한다.

GetDataDDEOrigin:어떤 클라이언트 어플리케이션이 데이터를 보냈는지 구한다.

RespondRemote:클라이언트에게 명령 또는 데이터가 서버에게 받아들여졌는지를 알려준

다.

SetDataDDE : 클라이언트 어플리케이션에게 데이터를 보낸다.

StartServerDDE:파워빌더를 서버로 동작하게 한다.

StopServerDDE:파워빌더가 서버로 동작하는 것을 중지한다.

7. 파일처리 함수  

FileClose  : 파일 닫기

FileDelete : 파일 삭제

FileExists : 파일 존재 유/무

FileLength : 파일 길이

FileOpen  : 파일 열기

FileRead  : 파일 읽기

FileSeek  : 파일 내 위치 이동

FileWrite  : 파일에 쓰기

GetFileOpenName:파일 열기 공통 다이얼로그 열기

GetFileSaveName:파일 저장 공통 다이얼로그 열기

8. 라이브러리 함수  

LibraryCreate:라이브러리 생성

LibraryDelete:라이브러리 삭제

LibrarDirectory:pb라이브러리 파일의 모든 오브젝트의 리스트를 구한다.

LibraryExport:라이브러리 파일의 모든 오브젝트를 Export한다.

Library Import!:지정한 라이브러리 파일에서 오브젝트를 Import!한다.

9.MAPI함수  

mailAddress        :메일 메세지에 주소를 주거나 주소 리스트를 보여준다.

mailDELETEMessage  :메일 메시지를 지운다.

mailGetMessages    :메지시 id를 얻어온다.

mailHandle          :내부 메일 시스템 핸들을 얻어온다.

mailLogOff          :메세징 시스템과의 세션을 끊는다.

mailLogOn          :메세징 시스템과의 세션을 시작한다.

mailReadMessage    :메일 메시지를 읽는다.

mailRecipientDetails:지정된 수취인의 주소 정보를 보여준다.

mailResolveRecipient:불분명한 수취인 명을 결정한다.

mailSaveMessage    :사용자 수신함에 새로운 메시지를 생성하거나 기존에 있는 메시

지를 대체한다.

mailSend            :메일 메시지를 보낸다.

10. 수치 처리 함수  

Abs        : 수치의 절대값을 얻는다.

Ceiling    : 지정한 수보다 크거나 같은 최소 정수를 구한다.

Cos        : 주어진 각도의 코사인 값을 구한다.

Exp        : e를 Number만큼 거듭제곱한 값을 구한다.(e=2.71828182845904)

Fact      : 계승값을 구한다. Number의 계승값은 1*2*3*...* Number이다.

Int        : 소수점 이하를 버리고 가장 가까운 정수로 변환한다.

Log        : 지정 숫자의 자연로그값을 구한다.

LogTen    : 지정한 숫자에 대해 밑이 10인 로그값을 구한다.

Max        : 두 수 중 큰 수를 구한다.

Min        : 두 수 중 작은 수를 구한다.

Mod        : 두 수를 나눈 나머지를 구한다.

Pi        : 3.14159265358979를 구한다.

Rand      : 난수를 구한다.

Randomize  : 난수 발생기를 초기화한다.

Round      : 숫자를 지정한 자릿수로 반올림한다.

Sign      : 숫자의 부호를 결정한다. Number가 양수이면 1을 표시해주고 0이면 0,

음수이면 -1을 표시한다.

Sin        : 주어진 각도의 사인 값을 구한다.

Sqrt      : 양의 제곱근을 구한다.

Tan        : 주어진 각도의 탄젠트 값을 구한다.

Truncate  : 숫자의 소수점 이하를 버리고 정수로 변환한다.

 

 

11. 출력(Print)함수  

Print      : 현재 글꼴로 문자열을 인쇄한다.

PrintBitmap: 지정한 인쇄공간에 비트맵 이미지를 인쇄한다.

PrintCancel: 인쇄를 취소한다.

PrintClose : 현재 페이지를 프린터에 보내고 인쇄를 멈춘다.

PrintDefineFont:인쇄작업시 폰트를 정의한다. 파워빌더는 각각의 인쇄 작업에 대해 8

가지 폰트를 제공한다.

PrintLine  : 지정한 위치에 지정한 굵기로 타원을 그린다.

PrintOpen  : 현재 페이지를 프린터에 보내고 새로운 페이지를 셋한다.

PrintOval  : 지정한 위치에 지정한 굵기로 타원을 그린다.

PrintPage  : 지정한 위치에 지정한 굵기로 둥근 모서리의 사각형을 그린다.

PrintRect  : 지정한 위치에 지정한 굵기로 사각형을 그린다.

PrintRouneRect:지정한 위치에 지정한 굵기로 둥근 모서리의 사각형을 그린다.

PrintSend  :지정한 문자열을 프린터에게 보낸다.

PrintSetFont:현재 인쇄 작업에 대한 글꼴을 지정한다.

PrintSetSpacing:라인간 너비를 지정한다.

PrintSetup : 프린터 설정 다이얼로그 박스를 부른다.

PrintText  : 지정한 위치에 지정한 문자를 인쇄한다.

PrintWidth : 현재 글꼴에서 지정된 문자열의 너비를 구한다.

PrintX    : 커서의 X좌표를 구한다.

PtintY    : 커서의 Y좌표를 구한다.

  

12. 문자열 처리 함수  

Asc        : 문자열의 첫번째 문자의 ASCII값을 구한다.

Char      : 주어진 ASCII값에 해당하는 문자를 구한다.

Fill      : 지정한 문자를 반복시켜서 문자열을 만든다.

Left      : 문자열의 시작부터 지정한 수의 문자를 읽어온다.

LeftTrim  : 문자열의 시작에 있는 공백을 없앤다.

Len        : 문자열의 길이를 구한다.

Lower      : 주어진 문자열 내의 대문자를 소문자로 고친다.

Mid        : 주어진 문자열에서 시작 위치와 끝 위치를 지정해 문자열의

            일정 부분만을 구한다.

Pos        : 다른 문자열에서 주어진 문자열의 위치를 찾는다.

Replace    : 문자열의 일부를 다른 문자열로 바꾼다.

Right      : 문자열의 끝에서 주어진 수의 문자를 얻어온다.

RightTrim  : 문자열의 끝에 있는 공백을 없앤다.

Space      : 지정한 길이로 공백 문자열을 얻는다.

Trim      : 문자열의 시작과 끝의 공백을 없앤다.

Upper      : 지정한 문자열 내의 소문자를 대문자로 고친다.

  

13. 시스템 및 환경 함수(System and Environment)  

Clipboard  : 윈도우의 클립보드의 내용을 얻는다.

GetApplication:현재 어플리케이션의 핸들을 구한다.

CommandParm: 어플리케이션 실행시 지정된 파라미터가 있을 경우 그값을 구한다.

DoScript  : 애플 스크립트(AppleScript)를 실행한다.(매킨토시 버전에만 해당)

GetEnvironment:시스템의 운영체제와 프로세서 등과 같은 정보를 얻는다.

Handle    : Window SDK함수를 부르기 위해 사용한다.

Post      : 지정한 윈도우에 대한 메시지를 메시지 큐에 마지막에 삽입한다.

ProfileInt : 지정한 프로파일에서 숫자값을 얻어온다.

ProgileString:지정한 프로파일에서 문자열을 얻어온다.

Restart    : 모든 스크립트의 실행을 중지하고, 모든 윈도우를 닫으며 데이터베이스

            Commit한후 연결을 끊고 다시 어플리케이션을 실행시킨다.

Run        : 지정한 어플리케이션을 실행시킨다.

Send      : 지정한 윈도우에 메시지를 순차적으로 보낸다.

SetProfileString:지정한 프로파일 값을 저장한다.

ShowHelp  : 윈도우 3.x에 있는 도움말(Help)파일을 읽어 파워빌더 어플리케이션에서

            사용할 수 있다.

SignalError: 어플리케이션 레벨에서의 시스템 에러를 발생한다.

Yield      : 반복문 안에서 다른 오브젝트나 어플리케이션의 메시지가 발생

            됐는지를 체크할수 있게 한다.

  

14. 시간처리 함수  

CPU        : 현재 실행중인 PB어플리케이션 프로그램의 시작 시간부터 현재까지의

            CPU시간을 구해준다.

Idle      : 사용자가 아무런 입력이 없이 지정한 시간이 흐르면 Idle이벤트

            발생시킨다.

Timer      : 지정한 윈도우에 일정한 간격의 타이머를 지정하여 Timer이벤트를

            발생시킨다.

  

15. 그밖의 함수  

Beep        : 정해진 시간(초단위)동안 경고음을 발생한다.

DBHandle    : DBMS의 핸들을 반환한다.

IsValid      : 지정한 윈도우가 열려있는지 검사한다.

KeyDown      : 사용자가 특정한 키를 눌렀는가 검사한다.

MessageBox  : 메시지 박스를 출력한다.

PixelsToUnits: 픽셀(Pixel)을 PB의 Unit로 바꾼다.

RGB          : 특정 색상을 표현하는 Long형 값을 반환한다.

SetNull      : 변수의 유형에 상관없이 변수를 Null로 지정한다.

SetPointer  : 마우스 포인터를 지정한 모양으로 바꾼다.

TypeOf      : 오브젝트의 형을 결정한다. 예를들면 CheckBox, Picture, RadioButton

등이다.

UnitsToPixels: PB의 Unit를 픽셀(Pixel)로 바꾼다.

 

 

1. UpperBound(배열명,{배열차원}) : 가끔 사용

  (1) 개념 : 배열의 가장높은 경계값을 알아낸다.

      Option으로 배열의 차원을 지정할 수 있으며 Default 차원은 1차원이다.

  (2) Return : integer(배열의 가장높은 경계값)

  (3) 예제

      가)

      integer li_number[7] , li_return

      li_return = UpperBound(li_number) // li_return 은 7이 된다.

      나)

      string ls_name[5,6] integer li_return

      li_return = UpperBound(ls_name,1) // li_return 은 5가 된다

      li_return = UpperBound(ls_name,2) // li_return 은 6이 된다

  (4) 메모 : 가변길이 선언 배열에서 ( ls_text[] )

  위의 함수를 사용하여 0이 Return되면 배열이 아직 현 메모리에 적재되지 않았음을

의미한다.

  (5) 상대함수 : LowerBound()

 

 

2. IsDate(string) : 자주 사용

  (1) 개념 : 특정한 String이 정확한 Date인지를 확인한다.

  (2) Return : Boolean ( Date가 맞으면 True 아니면 False이다. )

  (3) 예제 boolean lb_check

      lb_check = IsDate("1996/05/22") // lb_check 는 True이다

      lb_check = IsDate("1996/00/22") // lb_check 는 False 이다

  (4) 메모 : 특정한 String등을 Date로 변환시키기 직전에 많이 사용한다.

  (5) 유사함수 : Isnull() , Isnumber() , Istime() , Isvalid()

 

 

3. Date(datetime) , : 자주사용 Date(string) , Date(year,month,day)

  (1) 개념 : datetime , string , 년월일의 integer값을 Date 변수타입으로 변환한

  (2) Return : Date ( Valid 한 Date가 아닐때는 1900-01-01을 Return한다 )

  (3) 예제 datetime ldt_this date ld_new

      ld_new = Date(ldt_this)

      IF ld_new = Date("1900-01-01") THEN

          Messagebox("ERROR",'정확한 일자가 아닙니다 !!')

          return

      END IF

      ld_new = Date("1996/08/15") ld_new = Date(1999,11,23)

  (4) 유사함수 : DateTime()

 

 

4. Control명.ClassName() : 가끔사용 ClassName(변수명)

  (1) 개념 : 특정한 Object의 Class명을 String으로 알아낸다.

  (2) Return : String ( Error 발생시에는 empty string "" 이 반환된다)

  (3) 예제

      가)

      string ls_name

      ls_name = Parent.ClassName()

      IF ls_name = "w_insa001u" THEN

          sle_1.text = ls_name

      END IF

      // 어떤 Object의 Dragdrop Event 에서

      string ls_name dragobject ldr_what

      ldr_what = DraggedObject() ls_name = ldr_what.ClassName()

      IF ls_name = 'em_delete' THEN

          ldr_what.Drag(end!) Messagebox("Drag Object",'Drag된 Object 는 '& + ls

_name + '입니다')

      END IF

      나)

      long ll_qty string ls_class

      ls_class = ClassName(ll_qty) // ls_class 는 'long' 을 받아온다

      ls_class = ClassName(this) // ls_class 는 현 Object 의 Class 명칭을 받아

온다

5. Object명.PostEvent(event명) : 자주사용

  (1) 개념 : Script가 쓰여진 현 Event가 끝난뒤 특정 Object의 Event를 수행하게

한다.

      위의 function은 script가 쓰여진 위치에 관계없음으로 그 이후에 어떤 scrip

가 있다면

      그것을 모두 수행한후에 실행된다.

  (2) Return : Boolean (성공하면 true , event가 없거나 script가 없으면 false)

  (3) 예제

      cb_close.PostEvent(clicked!) // object에 기본적으로 있는 event일때

      cb_close.PostEvent("ue_keydown") // User가 정의한 event일때

6. Object명.TriggerEvent(event명) : 매우 자주사용

  (1) 개념 : 현 Event에서 어떤 특정Object의 특정Event를 즉각적 수행하고 돌아온

다.

      Script가 쓰여진 위치가 중요하다

  (2) Return : Boolean (성공하면 true , event가 없거나 script가 없으면 false)

  (3) 예제

      cb_check.TriggerEvent(clicked!) // object에 기본적으로 있는 event일때

      cb_check.TriggerEvent("ue_check") // User가 정의한 event일때

  (4) 메모 : 어떤 Event의 Script를 수행한다는 면에서는 Postevent와 Triggerevent

는 동일하며

      두 이벤트 중 어떤것을 써야할지의 선택기준은 현재의 Event가 수행되고 난뒤

      어떤 Event를 이어서 수행시키느냐 (Postevent) , 즉각적으로 어떤 Event를

      수행하느냐 (Triggerevent) 의 차이이다.

[이 게시물은 사랑니님에 의해 2009-08-02 15:39:07 PowerBuilder에서 이동 됨]

 

 

 

[출처] 파워빌더 기본 함수 (파워빌더 모임) |작성자 대박이

 

 

 

**************************[DW modify 함수 모음(예제위주)]*********************************

Child, popup and 명시한 내용으로 DataWindow object 정의를 변경시킴으로써, DataWindow object를 수정한다.

사용자는 property를 변경함으로써 DataWindow에 관한 출현, 모양, 데이터베이스 정보 등을

변경할 수 있다. 사용자는 DataWindow object에 관한 내역을 제공함으로써 object들을 추가

및 제거 할 수 있다.

 

 

[문법]

dwcontrol.Modify ( modstring )

 

 

[Argument]

dwcontrol

수정하려는 DataWindow control, DataStore, 또는 child DataWindow의 이름

modstring

수정내용을 명시한 값 (string).

 

 

[Return 값]

String.

처리에 성공하면 빈 문자열("")을 리턴하고 에러가 발생하면 에러 메시지를 리턴한다. 에러

메시지는 "Line n Column n incorrect syntax"의 형식을 취한다. 칼럼은 modstring의 컴파일된 텍

스트부터 시작하여 카운트 된다. argument 값중에 NULL이 있으면, Modify 함수는 NULL을

리턴한다.

 

 

[용법]

Modify 함수는 DataWindow painter에서와 같이 스크립트 내에서 많은 동일한 설정을 할 수

있도록 해준다. Modify의 전형적인 사용예는 다음과 같다:

☞색상, 텍스트의 설정상태 및 다른 object의 설정상태를 변경한다

☞하나이상의 테이블을 갱신하기 위하여 DataWindow내 서로다른 테이블의 갱신 상태를 변

경한다

☞DataWindow object SQL SELECT 문장의 WHERE 절을 수정한다

☞원하는 데이터를 명시할 수 있도록 Query 모드 또는 Prompt For Criteria로 돌아간다

☞Retrieve Only As Needed의 상태를 변경한다

☞DataWindow object의 데이터 소스를 변경한다

☞Print Preview 디스플레이를 제어한다

☞DataWindow object내에 line 또는 bitmap등과 같은 object를 삭제/추가한다

이들에 대한 각각의 예는 [예제]를 참조한다.

DataWindow object를 수정하기 위하여 modstring내에 3가지 유형의 문장을 사용할 수 있다.

Statement type

Use to

CREATE object(settings)

DataWindow object에 텍스트, 계산된 필드, 비트맵 등의 object를 추가한다. object를 생성하

려면, 그것을 정의하는데 필요한 충분한 정보를 반드시 제공하여야 한다. OLE object는 생성

할 수 없으며, DataWindow에 OLE object를 추가할 수도 없다

 

 

DESTROY [COLUMN] object

DataWindow object에서 object를 제거한다. object가 칼럼 이름이면, 칼럼과 버퍼로부터 그

칼럼의 데이터를 모두 제거하기 위하여 COLUMN 키워드를 명시한다

 

 

objectname.property=value

property의 값을 value로 변경한다. property는 objectname에관한 위치, 색상, 크기, 폰트 및

다른 설정상태 등을 제어한다. objectname이 DAtaWindow일 때, 데이터베이스 접근에 관한

property도 설정할 수 있다. DataWindow내의 object 리스트를 가지고있는 DataWindow

Reference는 각 object의 property와 값을 가지고 있다.

 

 

property의 명시는 다음과 같은 방법을 취한다:

·상수

·따옴표로 둘러싸인 상수

·표현식

 

 

Object 이름

DataWindow painter는 칼럼과 칼럼 레이블에 자동으로 이름을 부여한다. 사용자가

DataWindow object에 추가한 다른 object들은 이름을 부여하지 않는한 숫자로 구성된 문자열

로 암호화된 이름이 부여된다. (Describe 함수는 그 암호화된 이름을 나타내주지만, painter 내

에서 그것을 볼 수는 없다.) onject의 속성을 쉽게 기술하고 수정하려면, object에 이름을 부

여하도록 한다.

 

 

Modify 함수의 표현

DataWindow property에 관한 표현을 명시할 때, 그 표현식은 형식을 가지고 있어야 한다:

defaultvalue~tDataWindowpainterexpression

 

 

defaultvalue는 property에 관한 적절한 데이터 타입으로 변환될 수 있는 값으며, 그 뒤에 탭

(~t)이 뒤따른다. DataWindowpainterexpression은 어떠한 DataWindow painter 함수도 사용할 수

있는 표현식이다. 또한, 표현식은 반드시 그 property에 관한 적절한 데이터 타입을 평가할

수 있어야 한다. 사용자가 칼럼의 property를 설정하면, 그 표현식은 DataWindow내의 각

row에 관하여 평가하고, 그 데이터에 기초하여 다양하게 나타낼 수 있도록 해준다. 전형적

인 표현식은 If 함수를 사용하는 것이다.

'16777215 ~t If(emp_status=~~'A~~',255,16777215)'

modstring내에 표현식을 사용하려면, 다음과 같이 명시한다 (한줄로 입력한다).

modstring = "emp_id.Color='16777215 ~t If(emp_status=~~'A~~',255,16777215)'"

모든 property가 표현식을 받아들이는 것은 아니다. 각 property에 관한 자세한 내용은 DataWindow Object Properties를 참조한다.

 

 

Quotes 와 tildes

 

 

Modify 함수의 argument는 다른 문자열을 포함할 수 있는 문자열이므로, 사용자는 따옴표를

명시하기 위하여 특별한 문법을 사용할 필요가 있다. 문자열내에 따옴표를 명시하려면, 다른

타입의 따옴표를 명시하거나 (홑따옴표 안에 따옴표를 중첩시키거나) 따옴표 앞에 tilde (~)를

사용한다. 다은 레벨의 중첩일 경우, 문자 그 자신은 ~"로 명시하여야 하므로, 반드시 ~~ 뒤

에 ~"를 명시하여야 한다. 예를들어, 위의 예를 다른 방법으로 표현하면 다음과 같이된다:

 

 

modstring = "emp_id.Color=~"16777215 ~t If(emp_status=~~~"A~~~",255,16777215)~""

 

 

quotes 와 tildes에 관한 더 자세한 정보는 "quotation marks"를 참조한다.

 

 

변수를 가진 modstring

 

 

modstring내에서 메모리변수를 사용하기위하여, 프로그램 내에서 사용중인 메모리 변수를

포함할 수 있다. modstring의 한 부분을 연결 시킴으로써, 필요한 곳에 따옴표가 포함된 문

자열을 포함시킬 수 있다. 예를들어, 아래에있는 코드는 modstring을 위의 경우와 유사하게

구축한 것이지만, If 함수 안에있는 기본설정 색상 값과 두 개의 색상 값은 스크립트내에서

계산된다.

 

 

red_amount = Integer(sle_1.Text)

modstring = "emp_id.Color='" + &

String(RGB(red_amount, 255, 255)) + "~tIf(emp_status=~~'A~~'," + &

String(RGB(255, 0, 0)) + "," + String(RGB(red_amount, 255, 255)) + ")'"

 

 

다음의 유사한 예는 If 함수를 사용하지 않은 것이다. 표현식을 명시하지 않으면 값 주의에

따옴표를 사용할 필요가 없다.

 

 

modstring = "emp_id.Color=" + String(RGB(red_amount, 255, 255))

 

 

modstring을 공란으로 분리하여 각 property를 설정함으로써 Modify 함수를 한 번 호출하여

여러개의 property를 설정할 수 있다. 예를들어, 다음 문장은 한 줄로 작성한 것이다.

 

 

rtn = dw_1.Modify("emp_id.Font.Italic=0 oval_1.Background.Mode=0

oval_1.Background.Color=255")

 

 

그러나, 하나의 property를 설정하기 위하여 각각 Modify 함수를 한 번씩 호출하는 것이 문

장을 이해하고 디버깅하기에 더 쉽다.

 

 

Debugging tip

 

 

modstring을 구축하고 그것을 Modify 함수의 argument 변수에 저장한다면, Debug 모드 내에

서 그 변수의 값을 찾을 수 있다. Modify 함수의 에러 메시지가 칼럼 번호를 나타낼 때, 컴

파일된 modstring을 찾음으로써 문자들을 카운트 할 수 있다.

 

 

WHERE 절의 수정

 

 

효과적인 측면으로 보면, WHERE 절을 수정하기 위하여 SetSQLSelect 대신 Modify 함수를

사용하는 것이 더 좋다. Modify 함수는 syntax를 검증하지 않고 DataWindow object의 상태를

갱신하지 않기 때문에 더 빠르게 수행된다. 그러나, Modify 함수는 에러를 처리하기가 더 까

다롭다. SetSQLSelect는 syntax를 두 번 수정 (syntax가 수정되었을 때와 retrieve를 실행할

때) 하고 DataWindow object의 상태를 갱신한다.

 

 

PowerBuilder는 DataWindow 수정을 위하여 이미 많은 함수들을 포함하고 있다. Modify 함수

를 사용하기 전에, 변경할 수 있는 함수의 존재 여부를 체크 하도록 하자.

 

 

사용자는 전형적인 dot notation을 사용하여 object를 포함하고있는 DataWindow control의

property를 설정할 수 있다. 예를들어, control의 경계선을 설정하려면 다음과 같이 명시한다:

 

 

dw_1.Border = TRUE

 

 

[예제]

다음 예제들은 [용법]에 나열된 전형적인 사용 예를 설명한 것이다.

 

 

색상의 변경

Color property 설정의 효과는 수정중인 object에 의존한다. DataWindow object 전체의 배경색

을 설정하려면, 다음의 문법을 따른다.

dwcontrolname.Modify("DataWindow.Color='long'")

 

 

칼럼 또는 텍스트 object의 색상을 설정하려면, 유사한 문법을 사용한다.

dwcontrolname.Modify("objectname.Color='long'")

 

 

칼럼 또는 다른 object의 배경색을 설정하려면, mode 와 색상을 설정하기 위하여 다음의 문

법을 따른다.

dwcontrolname.Modify( "objectname.Background.Mode='<0 - Opaque, 1 - Transparent>'")

dwcontrolname.Modify("objectname.Background.Color='long'")

 

 

위 문법들의 실제 사용예는 다음과 같다.

DataWindow dw_cust의 배경 색상을 붉은 색으로 변경한다.

dw_cust.Modify("DataWindow.Color = 255")

 

 

DataWindow dw_cust의 salary 칼럼내의 값이 90000을 초과하면 적색으로 그렇지 않으면 녹

색으로 설정하여 텍스트를 나타낸다.

 

 

dw_cust.Modify("salary.Color='0~tIf(salary>90000,255,65280)'")

다음은 세가지 색상을 제공하기 위하여 하나의 If 함수를 포함시킨 것이다. DataWindow

dw_cust의 부서 ID가 200이면 녹색, 100이면 적색, 아니면 흑색으로 나타낸다.

 

 

dw_cust.Modify("dept_id.Color='0~t " &

+ "If(dept_id=200,65380,If(dept_id=100,255,0))'")

 

 

다음은 slaary 값에 따라 salary 칼럼의 배경색을 설정하기 위하여 If 함수를 포함시킨 복합적

인 표현식을 사용한 예이다. 연결되는 문자열의 각 위치는 각 라인으로 분리하였다. 또한,

설정된 색상이 보이도록 배격색상 모드를 투명으로 하였고, Modify 함수의 에러 메시지를 나

타내도록 에러 체크기능을 포함하였다.

string mod_string, err

long color1, color2, color3, default_color

err = dw_emp.Modify("salary.Background.Mode=0")

IF err <> "" THEN

MessageBox("Status", &

"Change to Background Mode Failed " + err)

RETURN

END IF

/* mod_string에 관한 Pseudocode :

salary가 10000 미만이면, 배경을 적색으로 설정한다.

salary가 10000 이상이고 20000 미만이면, 배경을 청색으로 설정한다.

salary가 20000 이상이고 30000 미만이면, 배경을 녹색으로 한다.

그 밖의 경우는 배경을 흰색으로 한다.

*/

color1 = 255 //적색

color2 = 16711680 //청색

color3 = 65280 //녹색

default_color = 16777215 //흰색

mod_string = &

"salary.Background.Color = '" &

+ String(default_color) &

+ "~tIf(salary < 10000," &

+ String(color1) &

+ ",If(salary < 20000," &

+ String(color2) &

+ ",If(salary < 30000," &

+ String(color3) &

+ "," &

+ String(default_color) &

+ ")))'"

err = dw_emp.Modify(mod_string)

IF err <> "" THEN

MessageBox("Status", &

"Change to Background Color Failed " + err)

RETURN

END IF

다음 예는 RadioButton 칼럼의 값이 "Y"일 경우 텍스트 색상을 적색으로 설정하고, 그 밖의

경우는 흑색으로 설정한다. 위의 경우와 같이 연결되는 문자열은 줄(line)로 분리하였다.

integer color1, default_color

string mod_string, err

color1 = 255 //적색

default_color = 0 //흑색

mod_string = "yes_or_no.Color ='" &

+ String(default_color) &

+ "~tif(yes_or_no=~~'Y~~'," &

+ String(color1) &

+ "," &

+ String(default_color) &

+ ")'"

err = dw_emp.Modify(mod_string)

IF err <> "" THEN

MessageBox("Status", &

"Modify to Text Color " &

+ "of yes_or_no Failed " + err)

RETURN

END IF

/*-----------------------------------------------*/

표시되는 텍스트의 변경

텍스트 object의 텍스트를 변경하려면 다음과 같은 문법을 사용한다.

dwcontrolname.Modify("textobjectname.Text='string'")

다음 문장은 DataWindow dw_cust내의 텍스트 object Dept_t 텍스트를 Dept로 변경한다.

dw_cust.Modify("Dept_t.Text='Dept'")

다음 장은 DataWindow dw_cust내의 dept_t의 텍스트를 부서 ID가 201 보다 크면 Marketing

으로, 그렇지 않으면 Finance로 설정한다.

dw_cust.Modify("dept_t.Text='none~t " &

+ "If(dept_id > 201,~'Marketing~',~'Finance~')'")

 

 

하나이상의 테이블 갱신

Modify 함수의 중요한 사용목적 중 하나는 하나의 DataWindow object에서 하나 이상의 테이

블 갱신이 가능하도록 만드는 것이다. 다음 스크립트는 DataWindow painter에서 updatable로

명시된 테이블을 갱신한 후, Modify 함수를 사용하여 join된 다른 테이블을 갱신 가능하게

만들고 키(key) 칼럼과 갱신할 칼럼들을 명시하는 것이다. 이러한 기법은 하나이상의 테이블

을 갱신하기 위하여 여러개의 DataWindow object를 생성 하거나 embedded SQL 문장의 사용

필요성을 제거해 준다.

 

 

예에서, DataWindow object는 두 개의 테이블 department 및 employee와 join되어있다: 우선, f

상태 flag가 재설정되 않도록 하면서 department를 갱신한다. 다음에 employee를 갱신 가능

하도록 하고 갱신한다. 모든 작업이 성공하면, Update 명령은 flag를 재설정하고 COMMIT

명령은 변경된 내용을 허락한다. 스크립트에서 재사용이 가능하도록 하려면, 반드시

department를 갱신가능한 테이블로 다시 만들어 놓아야 한다.

 

 

integer rc

string err

/* DataWindow의 SELECT 문장은 :

SELECT department.dept_id, department.dept_name,

employee.emp_id, employee.emp_fname,

employee.emp_lname FROM department, employee ;

*/

// department를 갱신한다

rc = dw_1.Update(TRUE, FALSE)

IF rc = 1 THEN

// department 칼럼들의 갱신 속성을 변경한다

dw_1.Modify("department_dept_name.Update = No")

dw_1.Modify("department_dept_id.Update = No")

dw_1.Modify("department_dept_id.Key = No")

// employee를 갱신 가능하도록 만든다

dw_1.Modify( &

"DataWindow.Table.UpdateTable = ~"employee~"")

//필요한 employee 칼럼들을 갱신가능하도록 한다

dw_1.Modify("employee_emp_id.Update = Yes")

dw_1.Modify("employee_emp_fname.Update = Yes")

dw_1.Modify("employee_emp_lname.Update = Yes")

dw_1.Modify("employee_emp_id.Key = Yes")

// employee 테이블을 갱신한다

rc = dw_1.Update()

IF rc = 1 THEN

COMMIT USING SQLCA;

ELSE

ROLLBACK USING SQLCA;

MessageBox("Status", &

"Update of employee table failed. " &

+ "Rolling back all changes.")

END IF

ELSE

ROLLBACK USING SQLCA;

MessageBox("Status", &

"Update of department table failed. " &

+ "Rolling back changes to department.")

END IF

 

 

WHERE 절의 추가

다음 스크립트는 WHERE 절을 포함하지 않은 SELECT 문장을 가지고 생성된 DataWindow

object에 WHERE 절을 동적으로 추가하는 것이다. (이 예는 원래의 SELECT 문장에 WHERE

절을 추가함으로, 원래 SELECT 문장이 WHERE 절을 가지고 있으면 그 WHERE 절을 제거

하는 코드가 추가로 필요하다) 이 기법은 WHERE 절 내의 argument가 실행 시에 변경될 수

도 있을 경우에 매우 유용하다.

 

 

원래 SELECT 문장은 다음과 같을 것이다:

SELECT employee.emp_id, employee.l_name

FROM employee

아마, 응용프로그램은 사용자의 선택에 기초하여 WHERE 절을 구축할 것이다. 예를들면;

WHERE emp_id > 40000

윈도우의 Open 이벤트 스크립트에서 원래 SELECT 문장은 instance 변수 original_select에 저장한다.

dw_emp.SetTransObject(SQLCA)

original_select = dw_emp.Describe("DataWindow.Table.Select")

CommandButton의 Clicked 이벤트 스크립트에서 instance 변수 where_clause에 저장된

WHERE 절을 original_select에 연결하고 DataWindow의 Table.Select property에 할당한다.

string rc, mod_string

mod_string = "DataWindow.Table.Select='" &

+ original_select + where_clause + "'"

rc = dw_emp.Modify(mod_string)

IF rc = "" THEN

dw_emp.Retrieve( )

ELSE

MessageBox("Status", "Modify Failed" + rc)

END IF

 

 

DataWindow painter내에 삽입된 따옴표

Sybase SQL Anywhere 와 ORACLE의 경우, DataWindow painter는 테이블과 칼럼이름 주의를

따옴표로 둘러싼다 (예, SELECT "EMPLOYEE"."EMP_LNAME"). 사용자가 따옴표를 제거하지

않는 한, 예제 WHERE은 반드시 이들 따옴표를 사용하여야 한다. 예를들면:

where_clause = " where ~~~"EMPLOYEE~~~".~~~"SALARY~~~" > 40000"

주의: 사용자가 명시하는 값들은 겹 따옴표를 사용하지 않는다.

Query mode 와 prompt for criteria

Query 모드는 데이터를 선택하는 조건을 사용자가 명시하도록 하는 DataWindow의 또다른

형식이다. PowerBuilder는 명시한 내용에 기초하여 WHERE 절을 구축한다. 사용자가 query

모드를 빠져나갈 때, 변경된 SELECT 문장에 기초하여 데이터를 retrieve 할 수 있다.

 

 

다음 예에서, DataWindow control을 나타내는 윈도우는 Select Data라는 메뉴를 가지고 있다.

사용자가 그것을 선택하면, 스크립트는 query 모드에서 DataWindow control을 나타내고 메뉴

아이템을 체크한다. 사용자가 그 메뉴를 다시 선택하면, 스크립트는 query 모드를 종료하고

사용자가 query 모드에서 명시한 새로운 WHERE 절에 기초하여 데이터를 retrieve 한다. 또

한 Sort라는 레이블을 가진 CheckBox를 윈도우에 나타나게하고, query 정렬 모드를 on 또는

off 한다.

 

 

Select Data 메뉴 아이템에관한 스크립트는 다음과 같다:

string rtn

IF m_selectdata.Checked = FALSE THEN

// 사용자가 데이터를 명시할 수 있도록 query 모드를 설정한다

rtn = dw_1.Modify("DataWindow.QueryMode=YES")

IF rtn = "" THEN

// Modify 함수처리에 성공하면, check 메뉴를 보여주고

// quiery 모드를 시작하고 정렬 CheckBox를 나타낸다

This.Check()

ParentWindow.cbx_sort.Show()

ELSE

MessageBox("Error", &

"Can't access query mode to select data.")

END IF

ELSE

// query 모드를 종료하고 사용자 선택에 기초하여 데이터를 retrieve 한다

rtn = dw_1.Modify("DataWindow.QueryMode=NO")

IF rtn = "" THEN

// Modify 함수 처리에 성공하면 uncheck 메뉴를 보여주고

// query 모드를 종료하고, 정렬 CheckBox를 숨기고,

// 데이터를 retrieve 한다

This.UnCheck()

ParentWindow.cbx_sort.Hide()

dw_1.Retrieve()

ELSE

MessageBox("Error", &

"Failure exiting query mode.")

END IF

END IF

 

 

Sort data CheckBox의 Clicked 이벤트의 스크립트는 간단하다.

IF This.Checked = TRUE THEN

dw_1.Modify("DataWindow.QuerySort=YES")

ELSE

dw_1.Modify("DataWindow.QuerySort=NO")

END IF

"Prompt for criteria"는 사용자가 가져올 데이터 기준을 명시하는 또다른 방법이다. 사용자는

column-by-column 단위로 설정한다. 스크립트에서 데이터를 retrieve 할 때, PowerBuilder는

Specify Retrieval Criteria 윈도우를 나타내어, 설정된 모든 칼럼에 관한 기준을 명시할 수 있

는 기회를 제공한다.

 

 

데이터를 retrieve 하기전에 실행되는 스크립트에서, 예를들면 DataWindow control을 나타내는

윈도우의 Open 이벤트에서, 다음 문장은 Retrieve 함수가 호출될 때 Specify Retrieval Criteria

대화상자를 나타내고 emp_name, emp_salary, dept_id 칼럼들의 설정을 가능하게 한다.

dw_1.Modify("emp_name.Criteria.Dialog=YES")

dw_1.Modify("emp_salary.Criteria.Dialog=YES")

dw_1.Modify("dept_id.Criteria.Dialog=YES")

query 모드 prompt for criteria 양쪽 모두에 영향을 주는 다른 Criteria property가 있다. 이들에

관한 자세한 내용은, Criteria DataWindow object property를 참조한다.

Retrieve as needed

다음 예에서, DataWindow object는 Retrieve Only As Needed가 선택된 상태로 설정되어있다. 이

옵션이 선택되어있을 때, PowerBuilder는 DataWindow를 채울 수 있는 row수 만큼 retrieve

한 후, 매우 빠르게 표시된다, 사용자가 다른 row를 나타내도록 시도할때까지 기다린다. 빠

르게 나타나기를 원하지만 서버에 open 되어있는 cursor를 떠나지 않기 바란다면, Modify 함

수를 사용하여 Retrieve Only As Needed를 off 시킬 수 있다.

 

 

row가 충분히 retrieve되었다고 결정한 이후에, RetrieveRow 이벤트내의 다음코드는

Retrieve.AsNeeded property를 변경하고, 나머지 row를 강제로 retirieve 한다.

dw_1.Modify("DataWindow.Retrieve.AsNeeded=NO")

 

 

데이터 source의 변경

다음 예제는 DataWindow object의 source를 SQL SELECT 문장에서 저장된 procedure로 변경

한다. 이러한 기법은 result set을 변경하지 않을 경우에는 작업 가능하다 (칼럼의 수, 타입,

순서등이 양쪽 source 모두 같아야 한다).

 

 

DataWindow object를 정의할 때, 사용가능한 DataWindow retrieval argument를 모두 미리 정의

하여야 한다. 예제에서, SELECT 문장은 타입이 각각 string, number, date인 3개의 argument를

가지고, painter내에 정의되어있다. stored procedure는 string 타입의 2두개의 argument만을 가

지고 있다. 따라서, painter 내에서, 2개의 string 타입, 1개의 number 타입, 1개의 date 타입

argument를 정의할 필요가 있다 (주의: 정의한 argument를 모두 사용할 필요는 없다)

 

 

string rc, mod_string, name_str = "Watson"

integer dept_num = 100

// DataWindow의 SELECT 문장을 제거한다

Dw_1.Modify("DataWindow.Table.Select = ''")

// Procedure property를 사용자의 procedure로 설정한다

mod_string = "DataWindow.Table.Procedure = &

'1 execute dbo.emp_arg2;1 @dept_id_arg &

= :num_arg1, @lname_arg = :str_arg1'"

rc = dw_1.Modify(mod_string)

// 변경이 받아들여지면, 데이터를 retrieve 한다

IF rc = "" THEN

dw_1.Retrieve(dept_num, name_str)

ELSE

MessageBox("Status", &

"Change to DW Source Failed " + rc)

END IF

DataWindow object내의 object 삭제와 추가

 

 

다음 문장은 DataWindow dw_cust로부터 logo라는 bitmap object를 삭제한다.

dw_cust.Modify("destroy logo")

다음 문장은 DataWindow dw_cust에서 salary 칼럼을 삭제한다. 주의: 예제에 column 키워드

가 포함되어 있으므로, DataWindow내의 칼럼과 데이터가 모두 삭제 된다.

dw_cust.Modify("destroy column salary")

다음 예제는 rect1 사각형을 DataWindow dw_cust의 header 영역에 추가한다. (modstring은 한

줄로 입력한 것이다)

string modstring

modstring = 'create rectangle(Band=background X="206" Y="6" height="69" width="1363" brush.hatch="6" brush.color="12632256" pen.style="0" pen.width="14" pen.color="268435584" background.mode="2" background.color="-1879048064" name=rect1 )'

dw_cust.Modify(modstring)

 

 

다음 문장은 DataWindow dw_cust의 grouping level 1 header 영역에 logo라는 bitmap을 추가한

다. (modstring은 한줄로 입력한 것이다)

 

 

string modstring

modstring = 'create bitmap(band=footer x="37" y="12" height="101" width="1509" filename="C:\PB\BEACH.BMP"

border="0" name=bmp1 )'

dw_cust.Modify(modstring)

object 생성 문법

object를 생성하려면 반드시 DataWindow syntax를 제공하여야 한다. 필요한 모든 property에

관한 syntax를 구하는 가장 쉬운 방법은 DataWindow painter내에서 object를 구성하고 그

syntax를 파일로 export하는 것이다. 다음에, 어떠한 원하는 부분을 변경하고 위에서처럼 스

크립트에 syntax를 집어넣는 것이다. 이것은 실제로 graph와 같이 복잡한 object에 관한 정

확한 syntax를 구할 수 있는 유일한 방법이다.

[출처] datawindow modify 함수 (파워빌더 모임) |작성자 좋은날

 

 

 

 

 

*******************[dw 두개를 같이 움직이기]************************************

Dw  Scrollhorizontal  event

 

 

 

Long  ll_hsplit1,  ll_hsplit2

 

 

 

ll_hsplit1 = Long(This.Object.DataWindow.HorizontalScrollPosition)

 

 

ll_hsplit2 = Long(This.Object.DataWindow.HorizontalScrollPosition2)

 

 

 

dw_list.Object.DataWindow.HorizontalScrollPosition   = ll_hsplit1

 

 

dw_list.Object.DataWindow.HorizontalScrollPosition2 = ll_hsplit2

 

 

 

 

 

Dw  lbuttonup event

 

 

 

Long  ll_hsplit

 

 

 

ll_hsplit = Long(dw_master.Object.DataWindow.HorizontalScrollSplit)

 

 

dw_list.Object.DataWindow.HorizontalScrollSplit = ll_hsplit

[출처] dw 두개 를 같이 움직이기 (파워빌더 모임) |작성자 드래곤

 

 

 

 

 

********[dw sqlpreview 이벤트에서 아래 스크립트를 작성하게 되면 retrieve시 sql이 작성된 노트패드가 출력됨]*************

if keydown(keyshift!) and keydown(keycontrol!) then

 FileOpen('.\temp_sql_' + this.classname() + '.txt',StreamMode!,Write!,LockWrite!,Replace!)

 long  ll_i

 

 FileWrite(1, '/*########## ' + this.classname() + ' = "' + this.dataobject + '" ##########*/~r~n~r~n~r~n')

 

 for ll_i = 1 to len(sqlsyntax) step 32765

  FileWrite(1, mid(sqlsyntax, ll_i, 32765))

 next

 FileClose(1)

 Run("notepad .\temp_sql_" + this.classname() + ".txt")

end if

 

 

 

 

 

*******************[상속받은 부모의 스크립트를 실행하지 않게 하기]*************************

스크립 작성 화면에서 오른쪽마우스를 누르면

나타나는 팝업 메뉴에서 Extend Ancestor Script 에 체크를

체크 Off 하면 부모쪽의 스크립은 수행되지 않습니다.</SCRIPT>

[출처] 상속받은 윈도우에서 부모창의 스크립트 실행하지 않기 (파워빌더 모임) |작성자 좋은날

 

 

 

 

 

*************************[테이블 또는 데이터 날라 날린것들 조회할 수 있는 과거 데이터 조회용 sql]*******************************

SELECT * FROM 테이블명 as of timestamp ( systimestamp - interval '30' minute) WHERE 1=1

 

 

많이들 알고 계시겠지만 테이블을 잘못 수정했을때 과거 내용을 찾는 오라클  timestamp 입니다.

30이라고 적힌것은 분으로 30분 전이라는 것이고요...   

WHERE절은 그대로 적으시면 30분 전 상태도 데이터가 조회됩니다.

오라클에서 360분까지만 지원된다고 하고요  시간때에 따라 시간을 지정해서 실행시키시면 됩니다.

데이터를 잘못 날리거나 잘못 수정했을때 사용하면 아주 유용합니다.

 

 

 

 

 

 

 

 

 

 

 

 

**********************************[엑셀 업로드 클릭 이벤트처리 excel upload]**************************************

string   ls_filename1,   ls_filename2,    ls_filename3,         &

          ls_err,         ls_src_cust_id,  ls_src_cust_id_sum,   &

          ls_src_cust_nm, ls_src_cust_ssn, ls_birth_ymd,         &

    ls_tel_home,    ls_tel_office,   ls_tel_etc,           &

    ls_tel_mobile,  ls_zip_no,       ls_addr_1,            &

    ls_addr_2,      ls_addr,         ls_last_call_stat_cd

    

integer   li_result

long      ll_camp_src_id, ll_row,          ll_idx,               &

          ll_cnt,         ll_cnt_sum,      ll_return,            &

    ll_camp_id,     ll_rtn,          ll_validation

datetime  ldt_fr_date,    ldt_sysdate

 

 

uo_msg.sle_msg.text = ''

 

 

//* Confirmation for ready to upload*//

SetPointer(Hourglass!)

dw_src_cust.Reset()

is_find = 'Y'

tab_1.TriggerEvent('ue_init')

cbx_all.Enabled  = TRUE

cb_delete.Enabled  = TRUE

dw_src_cust.SetRedraw(FALSE)

ldt_sysdate = uf_sysdate()

 

 

IF il_camp_id = 0 OR string(il_camp_id) = '' THEN

 MESSAGEBOX("Confirmation","Please select campaign!")

 tab_1.selectedtab = 1

 tab_1.tabpage_1.dw_campaign.SetFocus()

END IF

 

 

//* Find of excel or text file *//

li_result = GetFileOpenName ("Select File", ls_filename1, ls_filename2, "Excel Files (*.xls)", "All Files, *.*, Excel Files (*.xls), *.xls,CSV, *.csv")

   

IF li_result <> 1 THEN

 dw_src_cust.SetRedraw(TRUE)

 RETURN

END IF

 

 

//* File upload *//

li_result = uf_excel_import(ls_filename1, dw_src_cust, REF ls_err)

 

 

IF IsNull(li_result) OR li_result < 0 THEN

 dw_src_cust.Reset()

 dw_src_cust.SetRedraw(TRUE)

 RETURN

END IF

 

 

dw_src_cust.AcceptText()

ll_row = dw_src_cust.Rowcount()

 

 

IF ll_row < 1 THEN

 MESSAGEBOX("Confirmation","Can't find the customer to upload!")

 RETURN

END IF

 

 

hpb_1.position    = 0

hpb_1.maxposition = ll_row

hpb_1.visible     = TRUE

ll_validation = 0

 

 

//* Validation check *//

FOR ll_idx = 1 TO ll_row

 

 

 hpb_1.position = ll_idx

 

 

 ls_src_cust_id       = trim(dw_src_cust.GetItemString (ll_idx, 'src_cust_id'  ))

 ls_src_cust_nm       = trim(dw_src_cust.GetItemString (ll_idx, 'src_cust_nm'  ))

 ls_src_cust_ssn      = trim(dw_src_cust.GetItemString (ll_idx, 'src_cust_ssn'   ))

 ls_birth_ymd      = trim(dw_src_cust.GetItemString (ll_idx, 'birth_ymd'    ))

 ls_tel_home          = trim(dw_src_cust.GetItemString (ll_idx, 'tel_home'      ))

 ls_tel_office        = trim(dw_src_cust.GetItemString (ll_idx, 'tel_office'  ))

 ls_tel_etc           = trim(dw_src_cust.GetItemString (ll_idx, 'tel_etc'   ))

 ls_tel_mobile        = trim(dw_src_cust.GetItemString (ll_idx, 'tel_mobile'  ))

 ls_zip_no            = trim(dw_src_cust.GetItemString (ll_idx, 'zip_no'   ))

 ls_addr_1            = trim(dw_src_cust.GetItemString (ll_idx, 'addr_1'   ))

 ls_addr_2            = trim(dw_src_cust.GetItemString (ll_idx, 'addr_2'      ))

 ls_addr              = trim(dw_src_cust.GetItemString (ll_idx, 'addr'          ))

 ls_last_call_stat_cd = dw_src_cust.GetItemString    (ll_idx, 'last_call_stat_cd')

 

 

 IF Isnull(ls_src_cust_id) OR ls_src_cust_id = '' THEN

  ls_src_cust_id = '0'

 END IF

 

 

 IF Isnull(ls_src_cust_nm) OR ls_src_cust_nm = '' THEN

  ls_src_cust_nm = '0'

 END IF

 

 IF Isnull(ls_src_cust_ssn) OR ls_src_cust_ssn = '' THEN

  ls_src_cust_ssn = '0'

 END IF

 

 IF Isnull(ls_tel_home) OR ls_tel_home = '' THEN

  ls_tel_home = '0'

 END IF

 

 IF Isnull(ls_tel_mobile) OR ls_tel_mobile = '' THEN

  ls_tel_mobile = '0'

 END IF

 

 IF Isnull(ls_birth_ymd) OR ls_birth_ymd = '' THEN

  ls_birth_ymd = '00000000'

 END IF

 

 IF len(ls_birth_ymd) <> 8 THEN

  ll_validation = 1

 END IF

 

 dw_src_cust.SetItem(ll_idx, 'camp_id'     ,il_camp_id)

 dw_src_cust.SetItem(ll_idx, 'src_cust_id'   ,ls_src_cust_id)

 dw_src_cust.SetItem(ll_idx, 'src_cust_nm'   ,ls_src_cust_nm)

 dw_src_cust.SetItem(ll_idx, 'src_cust_ssn'    ,ls_src_cust_ssn)

 dw_src_cust.SetItem(ll_idx, 'birth_ymd'     ,ls_birth_ymd)

 dw_src_cust.SetItem(ll_idx, 'tel_home'       ,ls_tel_home)

 dw_src_cust.SetItem(ll_idx, 'tel_office'   ,ls_tel_office)

 dw_src_cust.SetItem(ll_idx, 'tel_etc'     ,ls_tel_etc)

 dw_src_cust.SetItem(ll_idx, 'tel_mobile'   ,ls_tel_mobile)

 dw_src_cust.SetItem(ll_idx, 'zip_no'     ,ls_zip_no)

 dw_src_cust.SetItem(ll_idx, 'addr_1'     ,ls_addr_1)

 dw_src_cust.SetItem(ll_idx, 'addr_2'       ,ls_addr_2)

 dw_src_cust.SetItem(ll_idx, 'addr'           ,ls_addr)

 dw_src_cust.SetItem(ll_idx, 'last_call_stat_cd'  ,ls_last_call_stat_cd)

 dw_src_cust.SetItem(ll_idx, 'etr_id'             ,gstr_user_stat.user_id)

 dw_src_cust.SetItem(ll_idx, 'etr_date'           ,ldt_sysdate)

 dw_src_cust.SetItem(ll_idx, 'mdf_id'             ,gstr_user_stat.user_id)

 dw_src_cust.SetItem(ll_idx, 'mdf_date'           ,ldt_sysdate)

 dw_src_cust.Setitem(ll_idx, "last_call_stat_cd", '10')

 dw_src_cust.Setitem(ll_idx, "src_stat_cd",       '10')

 

 SELECT COUNT(*)

 INTO   :ll_cnt

 FROM   TB_AO202

 WHERE  SRC_CUST_ID = :ls_src_cust_id

 AND    CAMP_ID     = :il_camp_id;

 

 IF ll_cnt > 0 THEN

  ll_cnt_sum += 1

 

  IF ll_cnt_sum = 1 THEN  

   ls_src_cust_id_sum = ls_src_cust_id

  ELSEIF ll_cnt_sum > 1 AND ll_cnt_sum <= 5 THEN

   ls_src_cust_id_sum = ls_src_cust_id_sum +', '+ls_src_cust_id

  ELSEIF ll_cnt_sum = 6 THEN

   ls_src_cust_id_sum = ls_src_cust_id_sum + '...'

  END IF

  

 END IF

 

 

NEXT

 

 

//* Check of src_cust_id for duplicate in database *//

IF ll_cnt_sum > 0 THEN

 uf_set_focus(dw_src_cust, ll_idx, 'src_cust_id')

 MESSAGEBOX("Confirmation",ls_src_cust_id_sum+" is Duplicated customer, Total count "+string(ll_cnt_sum))

 dw_src_cust.reset()

 dw_src_cust.SetRedraw(TRUE)

 hpb_1.visible = FALSE

 dw_src_cust.retrieve(il_camp_id)

 RETURN

END IF

 

 

//* Check of src_cust_id for duplicate in datawindow *//

IF ll_row > 1 THEN

 IF is_find = 'Y' THEN

  cb_cust_dup_check.TriggerEvent(clicked!)

  IF is_find = 'Y' THEN

   dw_src_cust.SetRedraw(TRUE)

   hpb_1.visible       = FALSE

   cb_update.Enabled   = FALSE  

   tab_1.TriggerEvent('ue_insert')

   RETURN

  END IF

 END IF

END IF

 

 

//* Check of data validation of birth_ymd *//

IF ll_validation = 1 THEN

 

 FOR ll_idx = 1 TO ll_row

  ls_birth_ymd = dw_src_cust.GetItemString(ll_idx, 'birth_ymd')

  IF len(ls_birth_ymd) <> 8 THEN

   dw_src_cust.SelectRow(ll_idx, TRUE)

   dw_src_cust.SetItem(ll_idx,'chk','Y')

  END IF

 NEXT

 

 dw_src_cust.SetSort("chk D, src_cust_id A")

 dw_src_cust.Sort()

 dw_src_cust.Scrolltorow(1)

 

 

 hpb_1.visible     = FALSE

 cb_update.Enabled = FALSE

 tab_1.TriggerEvent('ue_insert')

 

 

 MESSAGEBOX("Confirmation"," Save failed! ~n" + &

            " Please write your date of birth in YYYYMMDD format!")

 

 dw_src_cust.SetRedraw(TRUE)

 

 RETURN

 

END IF

 

 

//* camp_resource sequence generation *//

FOR ll_idx = 1 TO ll_row

 

 

 SELECT sq_camp_src_id.nextval

 INTO   :ll_camp_src_id

 FROM   dual ;

 

 dw_src_cust.SetItem(ll_idx,'camp_src_id',ll_camp_src_id)

 

NEXT

 

 

//* Update & Commit *//

ll_rtn = dw_src_cust.UPDATE()

IF  ll_rtn <> 1 THEN

    ROLLBACK;

 MessageBox("Confirmation"," save failed !!")

ELSE

    COMMIT;

END IF

 

 

//* Retrieve *//

dw_src_cust.retrieve(il_camp_id)

tab_1.tabpage_1.cb_sel_camp.TriggerEvent(clicked!)

tab_1.TriggerEvent('ue_init')

tab_1.tabpage_1.dw_campaign.Setredraw(FALSE)

tab_1.tabpage_1.dw_campaign.ScrollToRow(il_row)

tab_1.tabpage_1.dw_campaign.SelectRow(0, FALSE)

tab_1.tabpage_1.dw_campaign.SelectRow(il_row, TRUE)

tab_1.tabpage_1.dw_campaign.Setredraw(TRUE)

cbx_all.Enabled  = TRUE

cb_delete.Enabled  = TRUE

cb_update.Enabled   = TRUE

dw_src_cust.SetRedraw(TRUE)

hpb_1.visible       = FALSE

 

 

SetPointer(Arrow!)

uo_msg.sle_msg.text = ''

IF  ll_rtn = 1 THEN MessageBox("Confirmation","Upload & Save complete customer information!")

 

 

 

****************[엑셀업로드 펑션 excel upload function ]********************

oleobject ole_excel

Boolean lb_select, lb_delete

Integer li_connect, li_open

Long ll_xls, ll_row, ll_import, ll_txt_check

String ls_open_file, ls_save_file , ls_msg

 

 

SetNull(as_errOR)

ls_open_file = trim(as_path)

 

 

IF Len(ls_open_file) = 0 THEN

 as_errOR = "'Please enter the path"

  RETURN -10

END IF

 

 

IF NOT FileExists(ls_open_file) THEN

  as_errOR = "File does NOT exist"

  RETURN -10

END IF

 

 

 

IF pos(ls_open_file,'CSV') + pos(ls_open_file,'csv') > 0 THEN

   ll_xls = pos(ls_open_file,'CSV')  // Comma-separated file

   IF IsNull(ll_xls) OR ll_xls = 0 THEN ll_xls = pos(ls_open_file,'csv')

ELSE

   ll_xls = pos(ls_open_file,'xls')  // Excel file

   IF IsNull(ll_xls) OR ll_xls = 0 THEN ll_xls = pos(ls_open_file,'XLS')

END IF

 

 

IF IsNull(ll_xls) OR ll_xls = 0 THEN //* Excel OR txt file check

  ll_xls = pos(ls_open_file,'txt') // Tab-separated txt file

  

 IF IsNull(ll_xls) OR ll_xls = 0 THEN ll_xls = pos(ls_open_file,'TXT')

  

 IF NOT IsNull(ll_xls) OR ll_xls > 0 THEN

    ls_save_file = ls_open_file

   GOTO excel_import

 END IF

 

  as_errOR = "Is NOT excel file!."

  RETURN -10

END IF

 

 

ole_excel = CREATE OLEobject

 

 

li_connect = ole_excel.ConnectToObject("","excel.application")

IF li_connect = -5 THEN

  // -5 Can't connect to the currently active object

  li_connect = ole_excel.ConnectToNewObject("excel.application")

END IF

 

 

IF li_connect <> 0 THEN

  SetPointer(Arrow!)

  CHOOSE CASE li_connect

     CASE -1

       ls_msg = "Invalid Call: the argument is the Object property of a control~r~n"

     CASE -2

       ls_msg = "Class name NOT found~r~n"

     CASE -3

       ls_msg = "Object could NOT be created~r~n"

     CASE -4

       ls_msg = "ould NOT connect to object~r~n"

     CASE -9

       ls_msg = "Other errOR~r~n"

     CASE -15

       ls_msg = "MTS is NOT loaded on this computer~r~n"

     CASE -16

       ls_msg = "Invalid Call: this function NOT applicable~r~n"

     CASE ELSE

       ls_msg = "IF any argument's value is NULL, ConnectToNewObject RETURNs NULL.~r~n"

  END CHOOSE

  DESTROY ole_excel

  as_errOR = 'Excel program can NOT be executed. ~r~n'+ls_msg

  RETURN -10

END IF

 

 

SetPointer(HourGlass!)

 

 

ole_excel.Workbooks.Open(ls_open_file)

ole_excel.Application.Visible = FALSE

 

 

lb_select = ole_excel.Worksheets(1).Activate

 

 

ls_save_file = mid(ls_open_file, 1, ll_xls -2) + string(now(),'hhmmss') + ".txt"

 

 

ole_excel.Application.Workbooks(1).Saveas(ls_save_file, -4158)

ole_excel.Workbooks(1).Saved = TRUE

 

 

ole_excel.Workbooks.Close()

 

 

ole_excel.Application.Quit

ole_excel.DisConnectObject()

 

 

DESTROY ole_excel

 

 

excel_import:

 

 

ll_import = adw.importfile(ls_save_file,2)

SetPointer(Arrow!)

 

 

adw.AcceptText()

 

 

ll_txt_check = pos(as_path,'txt')

 

 

IF ll_txt_check < 1 THEN

 

 

 IF NOT FileDelete(ls_save_file) THEN

   MessageBox("ERROR", "Failed to file deleting.(" + ls_save_file + ")", StopSign!)

   RETURN -11

 END IF

 

END IF

 

 

IF ll_import < 1 THEN

  MessageBox("ERROR", "Failed to file handling!", StopSign!)

  RETURN ll_import

END IF

 

 

RETURN 1

 

 

 

 

 

 

****************************************[etc]**********************************************************************************************************************************

[TIP1] 데이터윈도우의 컬럼 헤더 텍스트를 클릭하면 해당 컬럼을 정렬하도록 하는 Clicked 이벤트 스크립트

string ls_name

IF dwo.Type = "text" THEN

dwo.Color = RGB(255,0,0)

ls_name = dwo.Name

ls_name = Left(ls_name, Len(ls_name) - 2)

This.SetSort(ls_name + ", A")

This.Sort()

END IF

 

 

// code라는 특정한 컬럼만 정렬되도록 지정 할 경우

 

 

string ls_name

 

 

IF dwo.Type = "text" AND dwo.Name = "code" THEN

dwo.Color = RGB(255,0,0)

ls_name = dwo.Name

ls_name = Left(ls_name, Len(ls_name) - 2)

This.SetSort(ls_name + ", A")

This.Sort()

END IF

 

 

 

[TIP2]

Datawindow에서 다중 테이블의 죠인에 의한 Multi Table Update를 가능하게 하는 방법

 

 

몇개의 Table을 Join하여 Datawindow를 만들었을때 Update characteristic에서하나의 Table에 대해서만 선택이 가능하며 다른 Table의 칼럼을 선택하여 OK를 누르면 선택된 Table의 칼럼이 아니라는 Error가 뜬다. 그러나 Update를 원하는 모든칼럼을 선택하고 여러 Table의 Key column을 선택할 수 있는 방법이 있다.

 

 

위와같이 필요한 모든 칼럼과 원하는 Option을 선택한뒤 Table to Update 필드에 임의 테이블명을 쓰고 (예:TEMP) OK 버튼을 누르면 Table 'TEMP' not found. Use table name anyway   라는 선택 메세지박스가 나타나는데 확인을 누르면 모든게 OK

이 방법은 물론 Update() 함수를 날릴때 Sqlsyntex를 확인해보면 알겠지만 Update나 Insert SQL문이 TEMP라는 Table로 날아감으로 Not Found Table이라는 Error가

발생할것이므로 미리 Modify("Datawindow.Table.UpdateTable = {table명}") 과

Modify("column명..Update = {yes/no}")을 해야하는 수고가 필요한

것은 같으나 선택한 column에 대한 Itemstatus를 내부적으로 Checking 하고있는것이 다르다.

보통 이렇게 쓰지않고 직접 SQL문장을 몇번씩 날리거나 보다 편하게 Stored Procedure를 사용하는게 속편하고 행복한( ) 방법이다.

 

 

[TIP3]

Funtion에서..

 

 

funtion을 만들때 Argument에 대한 특정한 Type을 지정을 하는데 선택할 수 있는 List에는 없지만 "dragobjct" 와 "blob"를 그냥 typing하여 사용할 수 있다.

특별히 쓰는곳이 없으신 분들이야 필요없겠지만 언젠가 필요할때 기억해두면 유용할것이다.

 

 

[TIP4]

Datawindow에서 Enter Key를 DoubleClick 또는 필요한 Event화 하기.

 

 

Datawindow에서 User Event를 pbm_dwnprocessenter로 Mapping하여 만든뒤 아래와 같은 script를 쓴다.

This.Postevent(doubleclicked!) This.Setactioncode(1)

 

 

다음 script를 쓰면 Enter Key가 Tab Key와 같은 역할을 하게되죠

send(handle(this),256,9,long(0,0)) this.setactioncode(1)

 

 

[Tip5]

FreeForm DW를 만들때 Design 높이를 정해놓기.

 

 

칼럼의 수가 몇개 되지 않는 데이타윈도우일때는 별문제없겠지만 상당한 수의 칼럼을 FreeForm Presentation Style로 Design할때에 column들이 아래로 계속내려가 있어 다시 정렬시에는 매우 번거러울 것이다.

그래서 새로운 Datawindow를 만드는 화면의 Option을 누르면 Wrap Height가 보이는데 이것을 적당한 크기로 선택하면 DW의 Detail의 높이를 한정할 수 있다.

 

 

[TIP6]

DataBase의 행동과 소요시간을 추적해 보기

 

 

Profile 을 setup할때 DBMS 부문 앞에 trace를 써주면 (예: trace OR7 ORACLE v7.x) Database의 traffic과 action들을 pbtrace.log 파일로 쌓아놓게 된다.

 

 

[TIP7]

DataWindow Error Message Title의 변경

 

 

데이타 윈도우에 Error가 발생하면 자체의 Error MessageBox가 뜨는데 Title이 항상 똑같아 보기에 별로다. 그래서 필요한 곳에 한번 아래와 같이 써주면 된다. dw_1.Modify("Datawindow.Message.title ='"+parent.title+"'") 물론 타이틀이야 본인이 원하는대로 하시길...

 

 

[TIP8]

가장 간단한 윤년 확인

 

 

ls_year = 원하는 년도

IF Isdate(ls_year + "/2/29") THEN

Messagebox("",'윤년이네 !')

END IF

 

 

[TIP9]

Window의 Timer Event를 이용하지 않은 시계만들기

 

 

1. Datawindow Object의 Attribute 중 Timer interval은 내부적으로

Timer를 발생시킨다. 이 Option을 1000으로하여 1초마다 변화를 발

생하게한뒤 Now() 함수를 쓴 Computed field를 만들어 Header에

위치시키면 시계가 된다. 물론 이 Datawindow는 Dummy column

한개의 External Datawindow로 만들면 될것이다.

 

 

2. 이러한 Timer interval을 응용하여 어떤 특정한 칼럼이나 Row를 깜

박이게 하거나 색을 반복적으로 변화시킬 수 있다.

원하는 Column의 Attribute 중 Visible에 다음과 같이 쓰거나

if(mod(integer(Mid(string(Now()),7,2)),2) = 1, 0 , 1)

Attribute 중 color에 아래와 같이 쓰면 된다

if(mod(integer(Mid(string(Now()),7,2)),2) = 1 , 0 , 255)

 

 

[TIP10]

특정한 각도의 Text 만들기

 

 

Datawindow에서 특정한 StaticText Object를 일정한 각도로 놓아

지게할려면 Attribute 중 Font Escapement에 필요한 수를 쓴다. 수

직으로 할려면 900 이다.

 

 

[TIP11]

고정된 Data를 Datawindow내부에 갖고 있기

 

 

데이타윈도우 Design 메뉴중 Rows/data 에 필요한 것을 써넣음. Retrieve가 필요없이 화면에 Data가 나타나므로 Design시 유용하다.

 

 

[TIP12]

Update된 특정 Row의 칼럼만 다시 Retrieve 하기

 

 

간단하다. Reselectrow() 함수를 사용하면 됨.

보통 모든 칼럼대비 10% 미만의 변화가 있을때 사용함이 유용하며 그 이상일때는 완전한 Retrieve() 함수의 사용이 보다 빠르다.

 

 

 

 

 

 

**********************************************[Path 지정]**********************************************

 

 

PowerBuilder로 만든 프로그램을 설치할때 필요한 run-time DLLs를 위해 Path를 설정 해야한다.

autoexec.bat file에서 Path문장으로 설정할 수도 있지만 Win95의 registry를 이용할 수도 있다.

 

 

'시작'의 '실행'에서 regedit를 하면 registry를 편집할 수 있다.

'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Apths'

 

 

항목을 선택하면 모든 실행화일 이름들이 나열되어있다.

거기에는 'Path'라는 값이 있고 거기에 실행파일에 필요한 path가 기재되어있다. 마우스 오른쪽버튼으로 path를 수정할 수 있다.

예를 들어 'myprog.exe'라는 프로그램을 설치한다면 App Paths밑에 'myprog.exe'라는 key를 만들고 Path값으로 'c\Program Files\Common Files\PowersoftShared;c:\SQLANY50\win32'하면 Windows는 실행파일에 필요한 내용을 찾을 수 있게된다.

 

 

 

 

 

 

**********************************************[pbm_syscommand Event]**********************************************

 

 

 

PowerBuilder 프로그래밍을 하다보면 response window를 많이 사용하게 된다.

response window에서는 'OK'라던가 'Cancel' button을 사용하게 되는데 사용자가 이 버튼만 사용한다고 말할 순 없다.

윈도우의 오른쪽 상단 구석에 보면 'x'표시가 있다.

마우스로 이걸 누르게 되면 윈도우는 close된다.

우리가 response window를 사용할때 main window와의 message 전달 수단으로 CloseWithReturn 함수를 사용한다.

따라서 main window는 responce window가 close되면 message객체에서 message를 참조하려 할것이고 사용자는 'OK'또는 'Cancel' 버튼으로 종료하지 않았으므로 message는 null값이 전달된다.

즉 실행중에 'null object referenced' error message가 발생한다.

이를 해결하기 위한 script로서는 pbm_syscommand로 User Event를 선언한다. 그런다음에 user event에 다음의 script를 기술한다.

ue_cancel은 cancel 버튼을 눌렀을 때 수행하는 내용과 같다.

그럼 ue_cancel에서 적당한 message를 전달하게 script를 작성하면 끝난다.

 

 

IF message.wordparm = 61536 THEN

this.TriggerEvent("ue_cancel")

END IF

 

 

 

 

 

 

**********************************************[LookUpDisplay(column)]**********************************************

 

 

 

Drop-Down DataWindow 또는 code table인 column을 sort key로 사용하는 경우

LookUpDisplay 함수를 사용한다.

DataWindow Painter에서 메뉴의 Rows - Sort를 선택한다.

'Specify Sort Columns' window에서 column을 drag하여 선택한다.

선택한 drop-down DataWindow 또는 code table edit style인 column을 더블 클릭하면 'Modify Expression' window가 뜬다.

그곳에서 column을 인자로 취하는 LookUpDisplay()함수를 사용한다.

 

 

예)

Specify Sort Columns

1) Drag and Drop items

2) Double clik column to edit

 

 

Source Data Columns Ascendin

emp_id LookUpDisplay(dept_id) *

dept_id

emp_fnam

emp_lname

 

 

그러면 dept_id code로 sort되지않고 dept_id의 display되는 값이 sort 기준이 된다.

 

 

 

 

 

 

 

 

**********************************************[SetMicroHelp]**********************************************

 

 

 

마우스를 어떤 control위로 이동시키면 microhelp message가 뿌려지는

프로그램을 본 일이 있을것이다.

이걸 PowerBuilder에서 구현하기 위한 Tip이다.

표준 Window event로써 pbm_nchittest가 있다.

이건 마우스가 어떤 control로 이동하면 자동으로 발생하는 event다.

예를 들어서 command button을 만들었다면 사용자가 마우스를 command button위로 이동시켰을 때 pbm_nchittest event가 발생한다.

그럼 우리는 pbm_nchittest event를 commnand button의 user event로 만들고 microhelp message를 뿌리는 script를 작성하면 끝이다.

message는 control의 properties... 의 Tag에 기술하고 pbm_nchittest

event의 script로서 다음과 같이 기술하면 된다.

 

 

g_w_frame.SetMicroHelp(this.tag)

 

 

g_w_frame은 MDI frame window를 가리키고 있다.

Tag가 싫다면 직접 string을 줘도 된다.

script는 여러분의 application에 맞게 기술하면된다.

user event만드는 방법은 해당 control의 script에 들어가서

메뉴의 Declare항목 User Events...를 선택하면 된다.

그럼 Events - controlname 이라는 window가 뜨고 거기에서 Event Name은 적당한 이름을 준다.

가능하면 we_nchittest라고 주는 것을 권장한다.

그리고 Event ID는 pbm_nchittest라고 주면 된다.

또는 Paste Event ID:라는 ListBox에서 찾아보면 있다.

더블클릭하면 해당 event id가 Event ID에 등록된다.

 

 

 

 

 

 

**********************************************[자동 Row 삽입]**********************************************

 

 

 

DataWindow에서 사용자가 맨 마지막 row 마지막 column에서 Tab Key를 누르면 자동으로 새로운 row를 insert해주는 Tip을 소개하겠다.

 

 

먼저 DataWindow에서 User Event를 선언하자.

선언할 User Event는 ue_tabout이라고 하고 사용할 User Event는 pbm_dwntabout이다.

이 Event는 사용자가 tab key를 입력해서 DataWindow를 벗어날때 발생하는 event다.

따라서 focus는 DataWindow가 아닌 다른곳으로 이동하게 되는 순간에 발생한다.

ue_tabout script는 다음처럼 기술하면 된다.

 

 

long l_row

 

 

l_row = this.InsertRow(0)

this.SetRow(l_row)

 

 

//DataWindow가 horizontal scroll bar를 갖도록 property를 설정한 경우.

this.Modify("datawindow.HorizontalScrollPosition = 1")

 

 

this.SetColumn("first_column")

this.SetFocus()

 

 

 

 

 

**********************************************[문자를 반짝이게(blink 기능)]**********************************************

 

 

DataWindow에서 display되는 문자를 반짝이게 하는 Tip이다.

문자를 반짝이게 하기 위해서는 DataWindow의 property중에서 timer inteval을 적당한 값으로 setting시켜야 한다.

10정도로 잡으면 된다. 그런다음 column이나 기타 control을 만들고 control의 property에서 Expressions의 visible에 다음 코드를 작성한다.

if(mod(Integer(Mid(String(Now(),),7,2)),2) = 1,0,1)

 

 

색변화를 주기위해서는 color에 다음 코드를 작성한다.

if(mod(Integer(Mid(String(Now(),),7,2)),2) = 1,0,255)

 

 

이렇게 하면 1초를 주기로 반짝이게 된다.

Now()는 현재 시간이고 Mid()로 초를 잘라내어 2로 나눈 나머지 값의 변화로 반짝이게 하는 것이다.

timer interval이 0으로 되어있으면 Now()는 처음 retrieve된 시간을 유지하게 되므로 반드시 timer interval을 줘야 한다.

 

 

 

 

 

**********************************************[ScrollToFirstRowOnPage]**********************************************

 

 

User가 DataWindow의 scrollbar를 눌러 scroll시킬때 row에 대한 highlight도 이동되도록 하는 Tip이다.

highlight되는 row는 현재 보여지는 page의 첫번째 row가 되도록 한다.

vertical scrollbar를 누르면 ScrollVertical event가 발생한다.

따라서 ScrollVertical Event에서 Describe()함수로 현재 보여지는 page의 첫번째 row의 값을 구해서 highlight를 설정하면 된다.

 

 

integer li_RC

long ll_row

string ls_result

 

 

// 현재 Page의 첫번째 row를 구한다.

ls_result = this.describe ( "DataWindow.FirstRowOnPage" )

if ls_result = "!" then

MessageBox ( "Error", "Describe failed (1)" )

halt close

end if

 

 

ll_row = long ( ls_result )

 

 

if ll_row < 1 then

MessageBox ( "Error", "Describe failed (1)" )

halt close

end if

 

 

// ScrollToRow함수로 상단의 row를 current row로 설정한다.

li_RC = this.ScrollToRow ( ll_row )

if li_RC <> 1 then

MessageBox ( "Error", "ScrollToRow failed" )

halt close

end if

 

 

 

 

 

**********************************************[Text at Any Angle]**********************************************

Text at Any Angle

 

 

이번은 아주 간단한 Tip이다.

DataWindow에서 static text또는 column등의 property에서 expressions list를 보면 font.escapement가 있다.

font.excapement property는 font가 display되는 각도를 지정하는 것이다. 즉 글자를 90도로 기울이고자 할때는 값을 900으로 맞춰주면 된다.

지정해주는 값은 각도*10을 하면된다. 즉 90도*10 = 900이다.

font.excapement를 지정함으로써 어떤 각도로든지 글자의 Angle을 조절할 수 있다.

font.excapement를 지정한 결과의 display형태는 DataWindow Painter에서 preview해보면 알 수 있다.

 

 

 

 

 

 

**********************************************[DataWindow Title bar]**********************************************

 

 

 

Window에 Title bar가 있듯이 DataWindow에도 Title bar가 있다.

DataWindow에서 Title bar를 사용하면 마우스로 DataWindow를 이동시킬 수 있게 된다.

하지만 DataWindow control에서 pbm_syscommand user event를 사용하면 DataWindow를 고정시킬 수 있다.

 

 

int a, b

 

 

a = message.wordparm

 

 

CHOOSE CASE a

CASE 61456, 61458

message.processed = true

message.returnvalue = 0

END CHOOSE

 

 

return

 

 

이렇게 pbm_syscommand에 script를 작성하면 마우스로 DataWindow를 이동시킬 수 없으면서 DataWindow에서 Title bar를 사용할 수 있다.

 

 

 

 

 

 

 

 

**********************************************[모든 칼럼의 tab order를 0으로]**********************************************

 

 

DataWindow에 있는 모든 column의 tab order를 zero로 setting하는 방법.

tab order를 zero로 설정하면 사용자는 Data를 수정하거나 입력할 수 없

게 된다.따라서 들어오는 사용자의 권한에 따라서 수정할 수 있게 또는 수정할 수 없게 프로그래밍하는 경우 유용한 Tip이다.

 

 

int i, i_count

 

 

i_count = integer(dw_1.Object.DataWindow.Column.Count)

 

 

FOR i = 1 TO i_count

dw_1.SetTabOrder(i, 0)

NEXT

 

 

 

 

 

**********************************************[DropDown DataWindow의 Display 값]**********************************************

 

 

 

DataWindow에서 Drop-Down DataWindow의 Display되는 값을 얻는 간단한 방법을 소개하겠습니다.

기존에는 DataWindow의 script에서 drop-down DataWindow의 display되는값을 얻기위해 GetChild함수를 사용해서 child datawindow를 구한다음에 getitem 종류의 함수로 display되는 값을 얻을 수 있었습니다. 버젼 4.0에선 그 방법밖에는 없었습니다. 하지만 버젼 5.0에선 child

datawindow를 사용하지 않고 한줄로 해결할 수 있습니다.

새로운 함수인 LookupDisplay함수를 사용하는 겁니다.

 

 

string s

long l_row

 

 

l_row = 3

//l_row는 DataWindow의 row 번호를 의미합니다.

//즉 우리는 3번 row의 dept_id column의 display되는 값을

//얻고자 합니다.

 

 

s = dw_1.Describe("Evaluate('LookupDisplay(dept_id)', " + &

String(l_row) + ")")

 

 

이렇게 하면 변수 s에는 dept_id의 코드값에 대응되는 dddw의 display

되는 문자열이 저장됩니다. 위의 Discribe의 인수로 주어지는 수식을 잘 보시면 됩니다.

 

 

Evaluate('LookupDisplay(dept_id)', 3)

 

 

 

 

 

 

**********************************************[RowCount in Footer]**********************************************

 

 

DataWindow painter에서 하단에 'Page 12 of 15'와 같은 내용의 computed column을 사용할 수 있다.

이건 간단하게 DataWindow painter에서 제공하는 computed column이다. 하지만 DataWindow preview를 해보면 하단 message bar에서'Rows 12 to 15 of 23'이라는 식의 내용을 볼 수 있다.

이러한 내용을 보여주는 computed column을 만들어 보자.

computed column을 DataWindow의 footer에 놓는다.

우선 간단한 방법으로...

computed column의 expression으로 다음과 같이 기술한다.

 

 

'Rows ' +

Describe("datawindow.firstrowonpage") +

'to ' +

Describe("datawindow.lastrowonpage") +

'of ' +

RowCount()

 

 

이렇게 하면 'Rows x to y of z'형식으로 항상 보여지게 된다.

하지만 retrieve된 row가 전혀 없을때도 'Rows 0 to 0 of 0'이라는 형식을 고수한다. 이것보다는 'No Rows'가 더 나을것 같다.

그리고 한page에 모든 Row가 보여질 정도로 적은 경우가 있다.

이러한 때는 'Rows x to y' 형식이 더 나을것 같다.

그래서 위의 expression을 수정해보자.

 

 

If( RowCount() = 0,

'No Rows',

If( Describe("datawindow.firstrowonpage") =

Describe("datawindow.lastrowonpage"),

'Row ' +

Describe("datawindow.firstrowonpage") +

'of ' + RowCount(),

'Rows ' +

Describe("datawindow.firstrowonpage") +

'to ' +

Describe("datawindow.lastrowonpage") +

'of ' +

RowCount()

)

)

 

 

 

 

 

**********************************************[반전된 로우의 해당 데이터값 간단하게 받기]**********************************************

 

 

long dept_id[], ll_row

 

 

FOR ll_idx = 1 TO dw_1.rowcount()

 IF dw_1.IsSelectedRow(row) = TRUE THEN

    dept_id[upperbound(dept_id[])+1] = dw_1.object.dept_id[row]

        END IF

next

 

 

 

long dept_id[]

 

 

dept_id = dw_1.object.dept_id.selected

선택(반전)된 데이터값 배열변수로 받아짐

선택된 데이터값 없을시 익스터널 에러

 

 

 

**********************************************[칼럼이름 저장하기]**********************************************

 

 

DataWindow에 있는 Column의 이름을 저장하는 방법입니다.

아주 간단한 Tip입니다.

 

 

String ls_string[]

int i

any ll_count

 

 

ll_count = dw_1.Object.Datawindow.Column.count

 

 

For i = 1 to integer(ll_count)

ls_string[i] = dw_1.Describe("#"+String(i)+".Name")

Next

 

 

이렇게하면 ls_string에 Column 이름이 들어가게 된다.

"#"+String(i)+".Name"을 잘 보세요.

Modify함수나 Describe함수에서 #1,#2 등은 Column을 의미합니다.

즉 DataWindow에서 Table의 Column을 선택할때 상단의 selection list 에 나오는 column의 순서를 #1등으로 표시하는 겁니다.

그럼 #1은 dwobject과 같은 type을 갖게 됩니다.

따라서 dwobject.name처럼 사용하면되죠.

DataWindow의 Itemchanged event에서 사용하는 dwobject처럼 사용하는 겁니다.

 

 

 

 

 

 

**********************************************[시리얼 통신]**********************************************

 

 

Win3.x에서 16bit PowerBuilder로 communication ports를 사용하는 것은 간단하다. 하지만 Win95/NT에서는 좀 어려운 작업이 필요하다.

왜냐하면 이들 OS는 communication port를 다른 방식으로 사용하기 때문이다. 즉 port를 file처럼 사용한다. 게다가 Win32 API 함수를 사용해야 한다. 또한 communication port file은 특별한 file이기 때문에 매우 특별한 방법으로 사용해야 한다. 먼저 Win32 API 함수가 필요하다.

 

 

/* To create a file */

 

 

function long CreateFileA(

 

 

ref string lpszName,

long fdwAccess,

long fdwShareMode,

long lpsa,

long fdwCreate,

long fdwAttrsAndFlags,

long hTemplateFile ) library "kernel32.dll"

 

 

/* to write to the file */

 

 

function boolean WriteFile(

 

 

long hFile,

ref string lpBuffer,

long nNumberOfBytesToWrite,

ref long lpNumberOfBytesWritten,

st_overlapped lpOverlapped ) library "kernel32.dll"

 

 

/* To close the file */

 

 

function long GetLastError() library "kernel32.dll"

 

 

/* To get error information */

 

 

function boolean CloseHandle(long hObject ) library "kernel32.dll"

 

 

위 4개의 API함수 ProtoType을 PowerBuilder에서 Global External Fucntions정의하는 곳에 기술하면 된다. 그럼 Script에서 참조할 수 있다. st_overlapped는 communication port로 쓰기를 시도할때 사용하는 structure다. 이것을 PB에서 정의한다.

 

 

$PBExportHeader$st_overlapped.srs

global type st_overlapped from structure

long Internal

long Internalhigh

long offset

long offsethigh

long hevent

end type

 

 

다음 예는 모뎀이 어떻게 전화를 거는지를 보여준다.

그외의 자세한 사항은 Win32 API HelpFile에 설명되어있다.

PowerBuilder에 있는 Watcom C++ compile에 보면 Helpfile이 있다.

 

 

/* declare the needed variables */

 

 

long ll_comid

long lnull

st_overlapped lst_overlapped

long ll_written

string ls_Port

string ls_Number

string ls_CRLF = "~r~n"

 

 

/* some constant, see helpfile for more information */

 

 

long GENERAL_WRITE = 1073741824

long SHARE_MODE = 0

long OPEN_EXISTING = 3

long FILE_FLAG_OVERLAPPED = 1073741824

 

 

/* port and number to dial */

 

 

ls_Port = "COM2"

ls_Number = "ATDT 0306090146" + ls_CRLF

setnull(lnull)

 

 

/* open the port by creating the 'file' */

 

 

ll_Comid = CreateFileA(ls_port,GENERAL_WRITE,SHARE_MODE,lnull, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,lnull)

 

 

IF ll_ComId >= 0 THEN

 

 

/* write the number to the port */

 

 

writefile(ll_ComId, ls_Number,len( ls_Number),ll_written, lst_overlapped)

messagebox("Yo!","Press Enter To Disconnect")

writefile(ll_ComId, ls_CRLF,len(ls_CRLF),ll_written, lst_overlapped)

 

 

ELSE

 

 

/* display error */

 

 

messagebox(string(ll_Comid),getlasterror())

 

 

END IF

 

 

/* close always */

closehandle(ll_ComId)

 

 

 

**********************************************[OpenWithParm]**********************************************

 

 

 

Window를 항상 Top위치에

 

 

Window가 다른 Window들 보다 항상 Top에 있어야할 필요가 있는 경우가 있다. Win3.1에서의 시계가 Option으로 항상 위에 있게 할 수 있게 되어있었다. PowerBuilder에서는 이것을 아주 간단히 구현할 수 있도록 SetPosition() method로써 제공하고있다.

 

 

SetPosition()에 사용되는 argument로서 TopMost!와 NoTopMost!가 있다. 이밖에 Behind!, ToTop!, ToBottom!이 있다.

winobj.SetPosition(TopMost!)로 하면 Window는 항상 Top위치에 있게 된다. 이를 해제할려면 winobj.SetPosition(NoTopMost!)로 하면 된다. 이밖에 ToTop!은 Window들 중에서 가장 높은 Top위치로 올리는 것이고, ToBottom!은 Window들 중에서 가장 낮은 Bottom위치로 내리는 것이다. Behind!를 사용할때는 Argument가 더 추가되어서 여러 Window들 중에서 몇번째 위치로 올려놓을 것인지를 지정해주어야 된다.

SetPosition() Method는 Window Object뿐만 아니라 Window에 있는 다양한Object에도 적용가능하다.

예를 들어서 겹쳐있는 DataWindow의 위치를 변화시켜줄 필요가 있는 경우에도 사용할 수 있다.

 

 

 

 

 

**********************************************[OpenWithParm]**********************************************

 

 

OpenWithParm을 사용하면 Open되는 Window로 필요한 parameter를 넘겨줄 수 있다.

하지만 PB에선 하나의 변수만 넘길 수 있다.(여러개를 넘길때는 structure를 사용한다.)

예를 들어서 OpenWithParm(w_abc,"hello"))은 PB의 global 변수인

Message.StringParm에 저장되어 전달된다.

OpenWithParm(w_abc, 34)하면 Global 변수인 Message.DoubleParm에 저장되어 전달된다.

그밖에 다른 Type의 값들인 경우는 MessagePowerObjectParm에 저장되어 전달된다. 그럼 하나이상의 값을 어떻게 전달할 수 있는가...

그건 structure object을 사용하면 된다.

structure object에 unbounded array를 정의하면 필요한 갯수만큼을 전달할 수 있다.

unbounded array는 실행시에 배열의 크기를 결정하는 형식이므로 얼마든지 많은 값을 전달할 수 있다.

structure painter에서 'Variable Name'을 s[]로하고 'Type'을 string으로 한다. 그럼 배열 s[]는 string을 저장할 수 있다.

계속해서 필요한 여러 Type의 배열을 정의해준다.

예를 들어서 double type의 d[], boolean type의 b[], datetime type의 dt[] 등으로 같은 structure안에 각각을 정의한다.

structure 이름을 str_parms로 한다면 아래와 같이 활용할 수 있다.

 

 

//Script에서 정의한 str_parms type의 structure 변수를 선언한다.

 

 

str_parms l_str_parms

//전달하고자 하는 값을 Type에 맞는 structure의 member에 치환시킨

//다.

 

 

l_str_parms.s[1] = "Smith"

l_str_parms.s[2] = s_company_name

 

 

OpenWithParm(w_abc, l_str_parms)

//w_abc의 Open event

//앞전의 script에서 보낸 structure가 전역변수인

//Message.PowerObjectParm에 저장되어 있다.

 

 

str_parms l_str_parms

 

 

l_str_parms = Message.PowerObjectParm

 

 

//여기서 전달받은 structure의 각각의 값을 사용한다.

//(ex. l_str_parms.s[1], etc.)

 

 

위와같은 방식은 CloseWithReturn 함수에서도 똑같이 적용된다.

 

 

 

**********************************************[MultiLineEdit에서의 TabKey사용]**********************************************

 

 

MultiLineEdit에서 입력중에 Tab key를 누르면 tab order 순서에 따라 focus가 이동된다.

이때 발생하는 event는 pbm_keydown 또는 pbm_dnwkey인데 이들 event를 직접 가로채서 MultiLineEdit에 tab문자나 Spaces문자를 입력하게 하는것은 힘들다.

하지만 Tab key에의한 Focus이동을 허용하지 않고 Tab문자나 Spaces문자를 MultiLineEdit에 입력하게 하고자 한다면 MultiLineEdit의 LoseFocus Event에서 Tab Key가 눌려졌는지를 KeyPress()함수를 이용해서 처리할 수 있다.

Tab Key가 눌려졌다면 원하는 문자를 입력하고 나서 User Event를 Post시켜서 focus를 SetFocus()함수를 사용해서 다시 MultiLineEdit로 돌려놓는다.

 

 

LostFocus Event

 

 

IF KeyDown(KeyTab!) THEN

this.ReplaceText(" ")

this.PostEvent("ue_setfocus")

END IF

 

 

 

 

 

 

 

 

**********************************************[WAV 화일 불러오기]**********************************************

 

 

 

waveform audio file을 연주하기 위해선 API함수를 사용해야 합니다.

이 함수는 SndPlaySoundA()함수입니다.

두개의 Parameter를 취하는데 하나는 .WAV file name 또하나는 연주하는 방법.

먼저 API함수를 사용하기 위해서는 Declare Menu에서 Local External Function을 선언해야 합니다.

Function Boolean sndPlaySoundA(String s_file, UINT u_flags) Library "WINMM.dll"

Function UINT LoadLibraryA(String as_library) Library "kernel32"

Subroutine FreeLibrary(UINT HInstance) Library "kernel32"

 

 

위에서 LoadLibraryA()함수는 멀티미디어 Library가 있는지 확인하는 함수.

그런다음 sndPlaySoundA()함수로 .WAV file을 전달한다.

연주가 끝난후에 메모리를 해제하기 위해서 FreeLibrary()함수가 호출된다. 다음의 예제 소스를 f_play라는 함수로 만들어 필요시에 사용하면 편리합니다.

 

 

return value는 None이고 Access 속성은 Public입니다.

 

 

UINT lu_instance

 

 

lu_instance = LoadLibraryA("WINMM.dll")

 

 

IF lu_instance = 0 THEN

sndPlaySoundA(as_wave, 0)

FreeLibrry(lu_instance)

END IF

 

 

return

 

 

위의 함수사용은 아주 간단합니다.

as_wave는 Argument로 받는겁니다.

즉 f_play("sound.wav")하면 됩니다.

sndPlaySoundA()함수에서 .WAV file을 지정할때 Path에 들어있는 file이어야 합니다. 그렇지 않으면 Directory도 지정해주어야 합니다.

두번째 Argument는 여러가지가 있습니다.

 

 

SND_SYNC 0 sound를 연주하고 return되기 전에 종료한다.

SND_ASYNC 1 sound를 연주하고 연주하는중에 return한다.

SND_NODEFAULT 2 WAV fiel이 발견되지 않았다면 default sound가 연주되지 않는다.

SND_MEMORY 4 file name이 memory안에 있는 image를 가리키고 있다.

SND_LOOP 8 SndPlaySound가 file name에 대해 NULL값을 가지고 호출 될 때까지 연주한다.

SND_NOSTOP 16 현재 sound가 연주중이면 FALSE를 return한다. 지정한 sound file이 발견되지 않으면 함수는 소리를 연주하지 않고 FALSE를 return합니다.

SND_NOSTOP Argument가 지정되어 있고 또 다른 Sound가 현재 연주중인 경우에도 FALSE가 return됩니다.

 

 

 

 

 

 

 

 

**********************************************[AVI 화일 보기]**********************************************

 

 

 

두개의 API함수를 사용해야 합니다.

micSendStringA()함수, 연주장치에 명령을 내보내는 역할을 합니다.

mdiGetErrorStringA()함수, 처리과정중에 관계된 에러를 보고합니다.

역시 API함수를 사용하기 위해서는 Declare Menu에서 Local External Function을 선언해야 합니다.

 

 

Function UINT LoadLibraryA(String as_library) Library "kernel32"

Subroutine FreeLibrary(UINT HInstance) Library "kernel32"

Function Boolean mciGetErrorStringA(long errorStr, ref string buffer,int wlength) Library "WINMM.dll"

Function Long mciSendStringA(ref string command, ref string returnstring,int wlength, UINT wcallback) Library "WINMM.dll"

 

 

Script는 좀 깁니다.

 

 

string ls_command, ls_buffer, ls_file, ls_path, ls_driver

long ll_error

UINT lu_lib

 

 

//멀티미디어 Library가 install되어 있는지를 loadlibraryA함수로 확인 //합니다.

IF lu_lib <> 0 Then

MessageBox("오류",'멀티미디어 디바이스 라이브러리가 없습니다.', &

StopSign!)

Else

FreeLibrary(lu_lib)

 

 

//AVIVideo device에 대한 registry를 찾는다 RegistryGet()함수가 0 // 을 return하면 video playback device를 갖고 있는것이고 -1을 ret // urn하면 컴퓨터에 비디오 실행을 위한 장치가 구성되어 있지 않다는 // 의미.

 

 

ls_buffer = "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control" + &

"\MediaResources\MCI\AVIVideo"

ll_error = RegistryGet(ls_buffer,"Driver",ls_driver

IF ll_error = -1 Then

MessageBox('오류','설치된 비디오 드라이브가 없습니다.', StopSign!)

Else

 

 

//device를 open하기 위해 command string을 작성한다.

//open하기 위한 file과 AVIVedeo Type, alias를 지정한다.

//alias는 후에 멀티미디어 함수 호출때 사용하기 위한것이므로

//아무렇게나 주어도 상관없다.

 

 

ls_buffer = Fill(char(0),255)

ls_command = "open music.avi type avivideo alias cartoon"

ll_error = mciSendStringA(ls_command, ls_buffer, 255, &

Handle(Parent))

//device를 open하는 동안 Error가 발생하였으면 ErrorMessage를

//얻어서 보여준다.

//정상적으로 open되면 mcisendStringA()함수에게 alias를 사용해 //서 file을 실행하라고 알려준다.

 

 

If ll_error <> 0 Then

mciGetErrorStringA(ll_error, ls_buffer, 255)

MessageBox('오류', ls_buffer)

Else

//연주가 끝났는지를 확인하기 위해서 Yield()함수를 사용한다.

Yield()

ls_command = 'play cartoon notify'

mciSendStringA(ls_command, ls_buffer,255, &

Handle(Parent))

Yield()

End If

End If

End If

 

 

 

window에서 pbm_mmmcinotify event ID를 이용 User Event를 만듭니다.

비디오 파일의 연주가 끝나면 이 이벤트가 구동하게 됩니다.

stript는...

 

 

String ls_command, ls_buffer

 

 

//device를 닫는다.

 

 

ls_command = 'close cartoon'

mciSendStringA(ls_command, ls_buffer, 255, Handle(this))

Yield()

 

 

 

 

 

**********************************************[MDI frame 작업공간]**********************************************

 

 

하나 이상의 컨트롤을 갖는 mdi frame을 custom mdi라고 한다.

MDI frame에 컨트롤을 추가하면 작업 공간을 바꾸어야 한다.

프레임에서 모든 컨트롤들은 일관된 이미지를 주기 위하여 위치와 크기가 정해져야 한다. 따라서 custom MDI frame을만들때는 frame의 resize event에서 mdi_1의 추가된 컨트롤의 위치와 크기를 바꾸어 준다.

처음 custom MDI frame에서 MDI_1의 높이와 넓이는 0이다.

만약 작업 공간이 없으면 Sheets는 열리지만 보이지 않으며, 작업 공간보다 Sheet가 더 크면 잘라져 버린다.

다음의 예처럼 마이크로 헬프의 기능을 대체하기 위해 userobject를 만든다고 하면,mdi의 크기가 조정이 되어야 할 것이다.

 

 

1) 먼저 작업공간(mdi_1)의 넓이와 높이를 얻는다.

 

 

int li_width, li_height

 

 

li_width = w_genapp_frame.WorkSpaceWidth()

li_height = w_genapp_frame.WorkSpaceHeight()

 

 

2) 새로 추가한 control을 제외한 새로운 작업 공간(mdi_1)의 크기를 계산한다.

 

 

li_height = li_height - (cb_print.y + cb_print.height)

li_height = li_height - MDI_1.MicroHelpHeight

li_height = li_height + WorkSpaceY()

 

 

3) 추가한 Control의 위치를 이동시킨다.

 

 

mdi_1.Move (WorkSpaceX(), cb_print.y + cb_print.height)

 

 

4) 작업 공간(mdi_1)을 변경한다.

 

 

mdi_1.Resixe(li_width, li_height)

 

 

 

 

 

 

**********************************************[Application Open Script]**********************************************

//application open event script

 

 

environment env //환경 설정에 관련된 변수를 정의한다.

string startupfile //ini파일을 정의 한다.

 

 

/* 시스템 환경 정보를 가져온다. */

IF (GetEnvironment(env) <> 1 ) THEN

MessageBox("Application Open ", "시스템의 환경을 알수가 없습니다!")

HALT

END IF

 

 

/* 각 시스템의 환경에 따라 적절한 INI파일을 설정한다. */

CHOOSE CASE env.OSType

CASE Windows!, WindowsNT!

startupfile = "pb.ini"

CASE Sol2!, AIX!, OSF1!, HPUX!

startupfile = ".pb.ini"

CASE Macintosh!

startupfile = "PowerBuilder Preferences"

CASE ELSE

MessageBox("Error","시스템의 환경을 알 수가 없습니다!")

HALT

END CHOOSE

 

 

/* PB.INI파일로부터 필요한 트랜잭션의 정보를 가져온다. */

SQLCA.DBMS =ProfileString("PB.INI","Database","DBMS", " ")

SQLCA.Database =ProfileString("PB.INI","Database","DataBase", " ")

SQLCA.LogID =ProfileString("PB.INI","Database","LogID", " ")

SQLCA.LogPass =ProfileString("PB.INI","Database","LogPassword", " ")

SQLCA.ServerName =ProfileString("PB.INI","Database","ServerName", " ")

SQLCA.UserID =ProfileString("PB.INI","Database","UserID", " ")

SQLCA.DBPass =ProfileString("PB.INI","Database","DatabasePassword", " ")

SQLCA.Lock =ProfileString("PB.INI","Database","Lock", " ")

SQLCA.DbParm =ProfileString("PB.INI","Database","DbParm", " ")

 

 

/* 데이터베이스에 연결한다. */

connect;

 

 

IF SQLCA.SQLCODE <> 0 THEN

MessageBox("데이타베이스에 연결할 수 없습니다!",sqlca.sqlerrtext)

RETURN

END IF

 

 

/* MDI frame 윈도우를 연다. */

Open(w_genapp_frame)

 

 

/****************************************************************/

/* uf_resized */

/* scope : public, parameters :없음 return 값 : 없음 */

/***************************************************************/

//uf_init()함수가 실행되지 않았을때이다.

IF ii_memi_ht = 0 THEN RETURN

 

 

//user object 의 크기나 위치를 변경할 때 성능을 위하여 hide시킨다.

Hide(This)

 

 

//모 윈도우의 크기대로 user object의 크기를 변경한다.

This.Width = iw_parent_window.Width

 

 

//각 Component의 크기를 변경한다.

st_clock.x = iw_parent_window.Width - (st_clock.Width + 38)

st_login_time.x = st_clock.x - (st_login_time.Width + 12)

st_msg.Width = st_login_time.x - (st_msg.x + 12)

 

 

//모 윈도우의 맨 하단으로 오브젝트를 이동한다.

Move{(This, 1, iw_parent_window.height - (this.height + ii_menu_ht) + &

ii_resizeable_offset)}

Show(This)

 

 

 

 

 

**********************************************[접속한 시간]**********************************************

 

 

//global variable

Time gt_s_time

 

 

/* 1login을 하는 해당 event에서 gt_s_time에 접속시간을 넣어준다. */

gt_s_time = Now()

 

 

 

/*f_login_time()만들기, 종료하는시점에서 불러오면 현재까지의 접속한 시간을 */

/* check해 준다.menu의 exit메뉴에서 호출하면 된다. */

 

 

time lt_start, lt_end

long ll_s_time, ll_e_time, ll_temp

string ls_hour, ls_minute, ls_second

 

 

lt_start = gt_s_time //처음에 login하던 시점의 시간.

lt_end = Now() //현재 접속종료하려하는 시점의 시간.

 

 

/* 시작과 종료시간의 차를 계산하기 위해서 모두 초단위로 변환한다. */

ll_s_time = Long(String(lt_end, "hh"))*3600 + &

Long(Right(String(lt_end, "hh:mm"),2))*60 + &

Long(String(lt_end, "ss"))

ll_e_time = Long(String(lt_start, "hh"))*3600 + &

Long(Right(String(lt_start, "hh:mm"),2))*60 + &

Long(String(lt_start, "ss"))

 

 

ll_temp = ll_s_time - ll_e_time

 

 

//초단위를 다시 시간, 분, 초단위의 time형식으로 변환한다.

ls_hour = String(Long(ll_temp/3600)) // 시간

ll_temp = Mod(ll_temp, 3600) // 시간단위변환후의 나

//머지값

ls_minute = String(Long(ll_temp/60)) // 분

ll_temp = Mod(ll_temp, 60) // 분단위변환후의

//나머지값

ls_second = String(ll_temp) // 초

// 종료시에 사용시간을 뿌려준다.

MessageBox("알림", "이용 하신 시간은 " + ls_hour + " 시간 " + &

ls_minute + " 분 " + ls_second + " 초 입니다! &

이용해 주셔서 감사합니다!")

 

 

 

 

 

 

**********************************************[라이브러리 최적화]**********************************************

 

 

Library는 2GB까지 확장할 수 있다. 그러나 Library가 너무 크면, 시스템의 디스크 접근 시간이 그 라이브러리를 읽는 데 많은 영향을 주게 된다. Library가 더 크게 되면, 더욱이 라이브러리 처리 엔진이 특정 OBJECTS에 대한 처리 요구를 수행하기 위해 큰 Library전체를 검색해야 할 필요가 생긴다.

 

 

Library의 엔트리수는 50~60이 적당하다.

라이브러리가 너무 많은 엔트리, 즉 오브젝트들을 갖고 있으면 라이브러리 페인터에서 엔트리가 열릴때의 작업이 불편하고 개발자 역시 라이브러리를 운영 유지하거나 관리하기가 더 어려워진다.

 

 

Library의 수와 양의 딜레마를 적절하게 조절한다.

라이브러리가 너무 크던가 너무 난잡하게 되는 것을 원하지 않는 곳과 마찬가지로, 너무 적은 OBJECT를 갖는 라이브러리도 좋지 않다.

경우에 따라서, 어떤 라이브러리는 1~2M의 크기가 될 수도 있을 것이다.

앞에서 말한 라이브러리의 크기와 그 오브젝트의 양에 대해서는 상호배타적인 관계를 가지고 있으므로 이러한 두 가지의 관계 사이에서 융통성을 가지고 운영하면 될 것이다.

 

 

어플리케이션을 개발하고 있는 프로젝트중, 많은 경우에 라이브러리의 수가 19개를 넘어갔을때에 문제가 종종 발생하는 경험을 한다.

그러나 라이브러리의 크기가 커서 문제가 되는 경우는 거의 없다.

이는 단지 속도 등의 성능에 관련된 문제이기 때문이다.

 

 

수시로 Library를 최적화(Optimize)한다.

개발을 진행하는 동안 라이브러리는 내부에 비활용 공간을 가지게 된다.

개발을 하는 중간중간에 라이브러리를 optimize해 줄 필요가 있다.

파워빌더가 관리하는 라이브러리의 내부 구조는 HDD와 비슷해서 어느 오브젝트의 크기가 커지면, 다른 위치에 연결된 구조를 가지게 되고 때론 사용하지 않는 조각들이 많이 존재하게 된다.

라이브러리 페인터에는 Optimize라는 유틸리티가 있다.

Optimize를 이용하여 라이브러리의 구조에 대한 최적화를 한다.

파워소프트사는 일주일에 한번 정도의 최적화를 권장하고 있다.

이런 최적화 작업은 단지 라이브러리의 내부 구조에 대한 작업일 뿐, 그 내용에 대해서는 아무런 영향을 미치지 않는다.

또한 개발이 종료되거나 테스트를 하기 전에는 반드시 PBD 파일이나 DLL, EXE파일을 만들기 전에 라이브러리를 최적화 해 주는 것이 좋다.

 

 

 

 

 

 

**********************************************[SQLDBCode의 사용]**********************************************

 

 

데이타 베이스를 CONNECT하고자 할때 비록 CONNECT에 실패해도 SQLCODE는 0을 리턴할때가 있다.

에러 메세지는 첫번째의 Data Retrieve 또는 Update를 수행할때 반드시 SetTrans 또는 SetTransObject를 기술하여야 한다는 것을 나타낸다.

그러므로 Connect가 발생하면 SQLCode 보다는 SQLDBCode를 체크해야 한다.

만일 SQLDBCode 가 0 이 아니면 connect되지 않았다는 것이다.

 

 

Connect Using SQLCA;

 

 

IF SQLCA.SQLDBCode <> 0 OR SQLCA.SQLCode <> 0 THEN....

 

 

FIELD NAME

RETURN VALUE

SQLCode

0 : 성공

100 : 발견되지 않음

-1 : sql error

SQLNRows

영향 미치는 row의 수

SQLDBcode

데이타베이스가 부여하는 에러코드

SQLErrText

데이타베이스가 부여하는 정보

 

 

단, DBMS가 SQLCA 트랜젝션 오브젝트가 생략되었다면 SQLDBCode나 SQLCode가 리턴되지 않는다.

DBMS가 확인되어지지 않았기 때문에, SQLDBCode 나 SQLErrText 에 대한

데이타베이스가 그것을 만들수 없게 된다.

 

 

 

 

 

 

**********************************************[DataWindow와 연결되는 4개의 버퍼]**********************************************

 

 

◈ Primary Buffer :

삭제나 여과가 안된 데이타를 포함한다.

데이타는 Retrieve와 InsertRow함수를 통하여 이 버퍼에 배치된다.

일단 Primary 버퍼에 포함된 데이타는 사용자에게 가시적이다.

 

 

◈ Filter Buffer :

Filter 함수를 통하여 실행시에 여과되는 데이타를 포함한다.

 

 

◈ Deleted Buffer :

데이타베이스에서는 아직 삭제되지 않았지만 DataWindow에서 삭제된 데이타를 포함한다. 데이타는 DeleteRow함수를 통하여 이 버퍼에 배치

된다.

 

 

◈ Original Buffer:

Update나 Delete문의 WHERE 절을 발생시키기 위하여 사용될 데이

타를 포함한다.

SQL UPDATE와 INSERT는 Primary and/or filtered 버퍼에 있는 데이타를 근거로하여 생성된다.

데이타윈도우가 갱신능력을 갖지 않으면, Deleted 나 Original 버퍼가 유지되지 않고, 그리고 어떤 SQL문도 Update함수에 의해 발생되지 않

는다.

 

 

 

 

 

**********************************************[Row와 Column의 Status]**********************************************

 

 

retrieve                = row : notmodified,  column : notmodified

modified                = row : datamodified, column : datamodified

1.insert                = row : new,          column : notmodified

2.insert후data입력상태  = row : newmodified,  column : datamodified

 

 

 

◈ sql문 생성

row의 상태

발생 명령문

NewModified!

Insert

DataModified!

Update

 

 

◈ DwSetItemStatus

datawindow의 row나 column의 상태를 변경하기 위해서 사용하는 함수

 

 

◈ DwGetItemStatus

datawindow의 row나 column의 현재상태를 알아보기 위해서 사용하는 함수

 

 

 

**********************************************[Return Value들..]**********************************************

◈ sqlcode에서

0 ok

-1 error

100 no data

 

 

◈ update에서

1 update함수 사용

-1 update함수 실패

dberror event발생

 

 

◈ retrieve에서

1 retrieve함수 성공

-1 retrieve함수 실패

dberror event발생

0 no data

dberror event발생하지 않음

 

 

◈ 4.0의 SetActionCode-->5.0의 return value

SetActionCode(0) ----> return 0 ----> 계속 실행

SetActionCode(1) ----> return 1 ----> 진행 멈춤

SetActionCode(2) ----> return 2 ----> 현재의 요청을 무시하고

다음의 요청을 실행

 

 

 

 

 

 

**********************************************[파워빌더에서 전화걸기]**********************************************

 

 

Declare 밑의 Local External Function에 다음과 같이 Script한다.

 

 

Function int OpenComm (string lpComName, uint wInQueue, uint wOutQueue) Librar

y "user.exe"

 

 

Function int CloseComm (int nCid) Library "user.exe"

Function int WriteComm (int nCid, string lpBuf, int nsize) Library "user.exe"

 

 

Function int FlushComm (int nCid, int nQueue) Library "user.exe"

 

 

Button Script 에 아래와 같이 Scriptd한다.

 

 

int li_comid

int li_rc

 

 

String ls_port // Poer No.

String ls_buffer /* 전화 번호(에를 들어 Pre Dial 이 있다면

9,01410 이런식으로*/

 

 

li_comid = OpenComm(ls_port,128,128)

If li_comid < 0 Then

If li_comid = -2 Then

Messagebox("Port: "+ ls_port + " In - Use","Error")

Else

Messagebox("Port: " + ls_port, "Error")

End If

Return -1

End If

 

 

Flushcomm(li_comid,0)

 

 

Flushcomm(li_comid,1)

li_rc = WriteComm(li_comid, ls_buffer, len(ls_buffer))

 

 

MessageBox("Dialing " + Left(ls_buffer,len(ls_buffer) - 2),"Hit Ok to hang up modem")

CloseComm(li_comid)

return 1

 

 

 

 

 

**********************************************[Null 값 핸들링시에]**********************************************

 

 

 

이번 Tip은 DataWindow Painter에서 NULL값을 처리하는 작은 트릭입니다. 일반적으로 '급여:' + String(salary) 라는 computed field를 사용할 수 있겠는데 만약 salary column의 값이 NULL인 경우 field또한 NULL값을 취하게 되어 아무런 값도 나타나지 않게 됩니다.

때문에 대개의 경우 IF문을 사용하지만 여기서는 String함수를 그대로 이용하는 방법을 소개합니다.

String함수의 mask는 number를 보기좋게 변환시켜주는 역할을 합니다.

mask는 number의 4가지 양태를 각각 지정할 수 있습니다.

즉 음수,양수,0,NULL 각각에 해당하는 mask를 semicolon으로 구분하여 별도로 지정합니다.

생략하는 경우 맨앞에 나타나는 mask로 처리됩니다.

'급여:' + string(salary, "#,##0; ; ; '(unknown)'")

위와같이 computed field를 사용하면 4번째 mask가 NULL인 경우에 적용됩니다. 즉 NULL인경우 '급여:(unknown)'이라고 나타나게 됩니다.

2번째,3번째는 생략되었기 때문에 1번째 mask 적용을 받게 됩니다.

이상의 설명은 String함수의 첫번째 Parameter data type이 number인 경우에 적용되는 팁이었습니다.

 

 

 

 

 

 

 

 

**********************************************[시스템환경을 체크해보자(cpu)]**********************************************

 

 

/* Declare */

Environment env

INTEGER resp

 

 

/* Variable Setting */

resp = GetEnvironment(env) //시스템 환경을 읽어오는 함수

 

 

CHOOSE CASE env.cputype //CPU의 TYPE(파워빌더는 14 //개 인식)

CASE alpha!

sle_1.text = 'Alpha'

CASE hppa!

sle_1.text = 'HPPA'

CASE i286!

sle_1.text = '286'

CASE i386!

sle_1.text = '386'

CASE i486!

sle_1.text = '486'

CASE m68000!

sle_1.text = '68000'

CASE m68020!

sle_1.text = '68020'

CASE m68030!

sle_1.text = '68030'

CASE m68040!

sle_1.text = '68040'

CASE mips!

sle_1.text = 'MIPS'

CASE pentium!

sle_1.text = 'Pentium'

CASE powerpc!

sle_1.text = 'PowerPC'

CASE rs6000!

sle_1.text = 'RS6000'

CASE sparc!

sle_1.text = 'Sparc'

END CHOOSE

 

 

 

 

 

**********************************************[시스템환경을 체크해보자(os)]**********************************************

 

 

/* Declare */

Environment env

INTEGER resp

 

 

/* Variable Setting */

resp = GetEnvironment(env) //시스템 환경을 읽어오는 함수

 

 

CHOOSE CASE env.OSType //OS TYPE(파워빌더는 7개 //인식)

CASE aix!

sle_1.Text = 'AIX'

CASE hpux!

sle_1.Text = 'HPUX'

CASE macintosh!

sle_1.Text = 'MacIntosh'

CASE osf1!

sle_1.Text = 'OSF1'

CASE sol2!

sle_1.Text = 'Solaris 2'

CASE Windows!

sle_1.Text = 'Windows'

CASE Windowsnt!

sle_1.Text = 'Windows NT'

END CHOOSE

 

 

sle_2.Text = Trim(Sle_1.Text) + ' ' + STRING(env.osmajorrevision) + &

'.' + STRING(env.osminorrevision) + &

'.' + STRING(env.osfixesrevision)

 

 

 

 

 

**********************************************[PowerBuilder의 버전]**********************************************

 

 

/* Declare */

Environment env

INTEGER resp

 

 

/* Variable Setting */

resp = GetEnvironment(env) //시스템 환경을 읽어오는 함수

 

 

CHOOSE CASE env.pbtype //현재 인스톨된 파워빌더의 type

CASE enterprise!

sle_1.Text = 'Enterprise'

CASE desktop!

sle_1.Text = 'Desktop'

END CHOOSE

 

 

IF env.win16 THEN

sle_2.Text = Trim(sle_1.Text) + "/16" + ' ' + &

STRING(env.pbmajorrevision) + '.' + &

STRING(env.pbminorrevision) + '.' + &

STRING(env.pbfixesrevision)

ELSE

sle_2.Text = Trim(sle_1.Text) + "/32" + ' ' + &

STRING(env.pbmajorrevision) + '.' + &

STRING(env.pbminorrevision) + '.' + &

STRING(env.pbfixesrevision)

END IF

 

 

 

 

 

**********************************************[Application의 환경]**********************************************

IF env.machinecode THEN //어플리케이션의 실행코드

sle_1.Text = "Machine Code"

ELSE

sle_1.Text = "P-Code"

END IF

 

 

st_colors.text =string(env.numberofcolors) //화면의 색상

st_height.text = string(env.screenheight) //화면의 높이

st_width.text = string(env.screenwidth) //화면의 너비

 

 

 

 

 

**********************************************[DataWindow에러 메시지의 변경]**********************************************

validation 오류 및 dw입출력 오류인 'DataWinodw Error'라는 Title의 Message Box의 title을 변경할 수 있다.

dw_1.Modify("DataWindow.Message.Title   = '입력오류'")

 

 

 

 

 

 

********************************[dynamic dw컴파일시 pbr확장자 파일 필요]***************************************************

Dynamic DW Object and Compile...

 

 

DataWindow control 이나 DataStore의 Object을 실행시에 Dynamic하게 변경시킬 수 있다.

이런 프로그램은 실행파일을 만들때 PBR(PowerBuilder Resource) file에 DataWindow Object name을 기술해줘야 한다.

DW Object을 dynamic하게 변동시키면 PowerBuilder에서는 문제없이 잘 실행되지만 실행파일을 만들어 보면 에러가 발생한다.

다음과 같이 dynamic하게 하는 경우는 반드시 PBR file을 작성해야한다.

 

 

dw_1.dataobject = 'd_employee_maint'

 

 

PBR file이 필요한 이유는 DataWindow object 이름이 인용부호로 둘러싸여 있기 때문에 compiler가 실행파일 만들때 DataWindow object이라고 인식하지 못한다. 따라서 DataWindow Object으로 포함시키지 않게된다. 그렇기 때문에 반드시 PBR file에 다음과 같은 내용을 기술해주어야한다. employee.pbl(d_employee_maint) PBR file은 매모장같은 곳에서 작성하여 .pbr 확장자로 저장시키면된다.

그런다음에 실행파일을 만드는 Project painter에서 PBR file 이름을

포함시켜 주면 된다.

 

 

 

*****************************************[드롭다운리스트 박스의 초기화]****************************************************

DropDownListBox의 Reset

 

 

DropDownListBox 가 처음 선택하지 않은 상태로 하려면

Allow Editing 이 가능할 경우에는 ddlb_1.text = "" 로 하면 초기화가 되지만 Allow Editing 이 불가능할 경우에는 ddlb_1.text = "" 로 해도 초기화가 되지 않는다. 이럴 경우에는 SelectItem() 함수를 사용한다.

ddlb_1.SelectItem(0) 하면 초기에 선택되지 않은 상태로 초기화 할 수 있다.

 

 

 

 

 

**********************************************[위아래 데이터 값이 동일한 경우 출력 안하게]*****************************************************

 

 

다음과 같이 자료가 display되는 경우 대분류의 중복 자료를 없애고자 한다.

Rows의 Supress Repeating Values를 사용하지만

대분류 중분류 소분류

1 12 23

1 22 33

1 23 43

2 24 53

2 25 63

2 26 73

 

 

다음과 같은 경우는 사용할수가 없다.

 

 

대분류 중분류 소분류

1  12 23

22 33

1  23 43

   24 53

2  25 63

2  26 73

 

 

이때는 Column Object의 Expressions의 Visible 속성에

다음과 같이 서술하면 된다.

 

 

if (a[0] = a[1] ,0,1)

 

 

물론 위의 경우도 Supress Repeating Values를 사용하지 않고

if (a[0] = a[-1] ,0,1)이라 서술하면 된다.

 

 

 

 

 

**********************************************[DW list에서 현재 row의 표시]*****************************************************

dw_employee.SetRowFocusIndicator(FocusRect!)

라고 미리 정해 놓으면 현재 row는 점선사각형으로 출력,

 

 

or

 

 

색변경 하는게 좋음

 

 

if(currentRow()= getrow(), RGB(238,249,255), RGB(255,255,255))

 

 

 

 

 

**********************************[DW argument like 절 사용시 null값 가져오기]*****************************************************

DW에서 like사용시 null컬럼 나오게

 

 

table test 의 컬럼이

empno,name,deptname,address,phone

(사번,이름,부서명,주소,전화번호)

라고 할때 datawindow를 디자인할때 주소로 검색할 경우

retrieve argument를 r_address 라고 할때

 

 

select empno,name,deptname,address,phone

from test

where address = :r_address;

 

 

로 정의한다.

그런데, 전체를 검색하기 위해 r_address 의 값을 '%'로 주었을 경우

address 컬럼이 null인 경우는 가져오지 못한다.

이럴 경우 다음과 같이 한다.

 

 

select empno,name,deptname,address,phone

from test

where ((address = :r_address) or

(address is null and :r_address = '%'))

 

 

 

※※ NVL(address,0) LIKE :r_address가 편하다. ※※

 

 

 

 

 

**************************[datetime 2000 날자 가져올때 형식 문제 해결]*********************************

 

 

2000년 문제

 

 

2000년 문제를 다루는 Tip으로서 그리 대단한건 아니지만 알면 도움될거 같아서 언급한다.

PowerBuilder의 DataWindow에서 Data를 Retrieve한다음에 메뉴의 SaveAs에서 일반 Text file로 저장하면 PowerBuilder은 Date또는 DateTime의 날짜부분을 yy/mm/dd 형태로 저장한다.

이렇게 저장된 파일을 import받으면 년수가 50보다 작을때 20xx가된다.

즉 2000년을 기본으로 계산한다. 50보다 크면 19xx가된다.

하지만 이런식의 저장과 import를 막기위한 방법이 있다.

PowerBuilder이 사용하는 yy/mm/dd의 기본형은 Windows95에서 참조하여 사용한다. 따라서 Windows95의 날짜 기본형을 정정하면 해결된다. 정정하는 방법은 Windows95의 제어판에서 국가별 설정을 선택한다.

그러면 국가별 설정 등록 정보의 날짜를 선택하여 간단하게 표기의 형식을

yyyy/mm/dd로 수정해주면 된다. 그러면 항상 PowerBuilder에서 그 형식을 기본형으로 사용하게되어 2000년 형식에서 오는 문제를 해결할 수 있다.

 

 

 

 

 

**************************[dddw trick 드롭다운 데이터윈도우 트릭]******************************************

 

 

Parent DataWindow가 retrieve되는 시점에 DropDown DataWindow(dddw)의 모든 내용이 retrieve된다.

어떤 사람이 parent datawindow의 clicked event에서 dddw.retrieve()를 하면된다는 그러한 솔루션을 제공한적이 있었다. 그것이 틀리다고 볼수는 없다.하지만 문제가 있다.

clicked event는 user가 dropdown 화살표를 click하던 일반 text column을 click하던간에 event가 발생된다는 것이다.

만일 click하는 지점이 일반문자(dddw의 화살표 옆에 있는 문자말고...)라면 program은 dddw.retrieve()하지말아야 한다. 따라서 그 방법은 이들간의 click 지점이 어딘지를 구분해야하는 script가 필요하다.

GetObjectAtPointer()와 GetClickedColumn()함수는 dddw가 click되어졌는지 아닌지를 알려주진 못한다.

따라서 몇가지 내부적인 Hacking에 의해 올바른 event는 pbm_dwndropdown이라는 결론에 이르게 되었다. 그래서 solution은 다음과 같다.

user event ue_dddw_dropdown을 만들자(pbm_dwndropdown을 mapping) 그리고 다음과 같은 script를 작성한다.

 

 

1) DataWindowChild dwc

dwGetChild(GetColumnName(), dwc)

dwc.SetTransObject(SQLCA)

dwc.retrieve()

 

 

위의 것은 기본적인 기능을 구현한 것이고 다음은 여러 개선사항을 첨가한 예다.

 

 

2) dwGetChild(GetColumnName(), dwc)

// 만약 dwc.rowcount()>1 이라면 그러면 dddw는 이미 한번

// drop down했다는 것이다. 따라서 귀찮게 다시 retrieve() 할 // 필요없다.

// 또하나 주의할것이 있다. dddw는 하나의 단일 row 즉 blank // 인 단일 row를 기본적으로 갖는다.

 

 

if dwc.rowcount() > 1 then return

 

 

dwc.SetTransObject(SQLCA)

dwc.retrieve()

3)위의 (1)과 동일한 방법

dwc.retrieve(GetText())

 

 

dddw의 SQL문장:

select country_name from contry_lookup

where country_name like :retrieve_argument + "%"

 

 

위의 것은 만약 user가 'ca'를 입력해서 dropdown 화살표를 click하면 국가이름의 목록이 아주 보기좋게 drop down될것이다.

 

 

cambodia

cameroon

canada

.

.

하지만 france나 sussia같은 국가명은 retrieve되지 않는다. 왜냐하면 SQL문장의 like구문에 의해 ca로 시작하는 것만 retrieve하기 때문이다.

이건 retrieve량을 줄이게되어 메모리 절약등의 효과도 있게된다.

그런데 만일 dddw가 employee_name이고 department field가 있다고 생각한다면...

회사의 사원은 상당히 많다 따라서 department에 'Information Service'라고 입력한다. 그리고 employee_name field로 이동하여 dddw의 화살표를 click하면 dddw는 오직 Information Service에서 일하는 사원만을 retrieve하게된다.

 

 

//(1)과 같은 방법

dwc.retrieve(GetItemString(GetRow(), "department"))

 

 

dddw의 SQL문장:

select employee_name from employee_table

where department = :retrieve_argument

 

 

여기까지의 설명에서 주 요점 사항으로 기억할것은 pbm_dwndropdown event를 이해하고 사용하는 것이다. 이건 undocumented event다.

 

 

 

 

 

***************************[위 아래 row 값 변경시 색깔 변경 expression 스크립트]***********************************

 

 

DataWindow, refer to data in a different row.

DataWindow에 product_id라는 column이 있다.

product_id값을 검사하여 product_id값이 변경되면 글자색도 변경하고자 한다. 이런 경우 현재 row의 product_id값과 다음 row의 product_id값을 비교할 수 있다면 간단해진다.

DataWindow에서 각각의 column은 마치 배열처럼 취급할 수 있다.

즉 row는 column의 첨자라고 볼 수 있다.

이러한 특징은 script 작성시에 많이 느낄 수 있을 것이다.

그러나 DataWindow field에선 좀 다르다.

현재 row는 0이고 그 다음 row는 -1, -2, -3으로 나간다.

그 전 row는 1,2,3,4.. 가 된다.

따라서 위의 문제가 아주 간단히 해결된다.

 

 

if ( product_id = product_id[-1], rgb(0, 0, 0), rgb(255, 0, 0) )

이러한 식을 product_id 의 color property에 기술하면 간단히 해결된다.

 

 

 

 

 

 

***********************[Multi_select : shift 로우 선택 기능 - 처음 클릭과 나중 클릭 사이의 row를 전체 선택]*********************************************

윈도우즈의 화일관리자등을 보면 Ctrl+Click 의 경우 계속해서 선택하고

Shift+Click 의 경우 처음 클릭과 나중클릭의 자료를 전부 선택하는 기능을 DataWindow에 적용해 보았습니다. 먼저 Global 함수를 다음과 같이 만듭니다.

----------------------------------------------

함수명 : gf_multi_select

전달값 : a_dw (DataWindow type)

----------------------------------------------

long w_rownum,w_selrow,i

w_rownum = a_dw.GetClickedRow()

if w_rownum <= 0 then return

if keydown(keyshift!) then

w_selrow = a_dw.GetSelectedRow(0)

if w_selrow > 0 then

for i = min(w_selrow,w_rownum) to max(w_selrow,w_rownum)

a_dw.SelectRow(i,true)

next

else

a_dw.SelectRow(w_rownum,true)

end if

elseif keydown(KeyControl!) then

if a_dw.isSelected(w_rownum) then

a_dw.SelectRow(w_rownum,false)

else

a_dw.SelectRow(w_rownum,true)

end if

else

if a_dw.isSelected(w_rownum) then

a_dw.SelectRow(0,false)

else

a_dw.SelectRow(0,false)

a_dw.SelectRow(w_rownum,true)

end if

end if

 

 

이 함수를 해당 DataWindow의 Click Event에서 부르면 됩니다.

 

 

dw_1의 click event

 

 

gf_multi_select(this)

 

 

 

 

 

*************************************[HorizontalScrollposition변경]*********************************************

((HScroll))

THIS.Object.DataWindow.HorizontalScrollPosition2  = 4050

((HSplitScroll))

THIS.Object.DataWindow.HorizontalScrollPosition   = 4050

 

 

IF ddlb_condition.text = '등록일자' THEN

 

 THIS.Object.DataWindow.HorizontalScrollPosition2  = 0

 

ELSEIF ddlb_condition.text = '주문번호' THEN

 

 ll_col_x     = long(THIS.describe("ord_id.x"))

 ll_col_width = long(THIS.describe("ord_id.width"))

 THIS.Object.DataWindow.HorizontalScrollPosition2  = ll_col_x - ll_col_width

 

ELSEIF ddlb_condition.text = '문의번호' THEN

 

 ll_col_x     = long(THIS.describe("inquiryid.x"))

 ll_col_width = long(THIS.describe("inquiryid.width"))

 THIS.Object.DataWindow.HorizontalScrollPosition2  = ll_col_x - ll_col_width * 3

 

END IF

 

 

 

 

 

*********************[초단위를 시간분초형식 변환]****************************

예를 들어 1000초가 있는데 이걸 시간 (hh:mm:ss) 형식으로 바꾸고 싶다면..

 

 

 

select  trunc (1000 / 3600, 0) as hours,

        trunc (1000 / 60  , 0) as minutes,

        mod(1000 , 60)  seconds

  from  dual;

 

 

 

OR

 

 

RelativeTime('00:00:00', 1000)

 

 

 

 

 

*****************************[DW where절 argument 팁(flag 형식)]***************************************

SELECT AJ070.NAVER_INQUIRY_ID      NAVER_INQUIRY_ID    ,

        AJ070.CATEGORY1                CATEGORY1           ,

        AJ070.CATEGORY2                CATEGORY2           

FROM   TB_AJ070                    AJ070

WHERE  ((:al_flag = 0  AND  TRUNC(AJ070.ETR_DATE)  >= :adt_fr_date AND TRUNC(AJ070.ETR_DATE) <= :adt_end_date)     OR

        (:al_flag = 1  AND  NVL(AJ070.ORD_ID,0)    = DECODE(:al_ord_id,    0, NVL(AJ070.ORD_ID,0),    :al_ord_id)) OR

        (:al_flag = 2  AND  NVL(AJ070.INQUIRYID,0) = DECODE(:al_inquiryid, 0, NVL(AJ070.INQUIRYID,0), :al_inquiryid)))

ORDER BY AJ070.NAVER_INQUIRY_ID

728x90

댓글