[ 파워빌더.Datawindow의 event강제 실행 ]

 

☞   첫 번째 방법

 


        dw_1.event itemChanged(값이수정된 해당row, 칼럼명.object, 입력된 문자값)
 
        dw_d2.SetItem(ai_row, "PART_CD", ls_last_part_cd);
        
        dwobject ldwo
        ldwo  = dw_d2.object.__get_attribute("PART_CD", true)
        dw_d2.event itemChanged(ai_row, ldwo, ls_last_part_cd);

☞  두 번째 방법

 

[event를 강제 호출하기]

 

help의 datawindow itemchanged를 찾아보면

itemchanged(row, dwo, data)

이것을 적용하면 아래와 같이

dw_d1.TriggerEvent ItemChanged(1, dw_d1.Object.uniform_num, string(ist_parm.uniform_num))

하면 되요.

data는 string 형태라 바꿔주었네요.

Posted by 농부지기
,

[ 파워빌더.DDDW - 태그(tag) 활용해서 dddw 자동으로 조회 ]

 

 

☞   

 

참고 글)tag 활용하기 http://cafe.naver.com/pentaeduclub/2523
자동으로 윈도우내 모든 데이터윈도우 dB 연결하기 2 http://cafe.naver.com/pentaeduclub/7486

 

 

-----------------------------------------------------------

dw의 각 컬럼마다 보시면, property에 tag가 있다.

이를 이용해서 dddw에 아규먼트가 있어서 조회를 시켜줘야 하는 컬럼에 대한 자동 조회로직을 만들어 보자.

물론 아규먼트가 없는 dddw는 auto retrieve 속성만 체크해주면  되기 때문에 별 상관없다.(하위 버전은 안될 수도 있음)

 

방식은 간단하다.

dddw 가 있는 컬럼의 태그에 아규먼트 값을 적어주는 것이다.

단, 전제조건은 공통코드 값처럼 고정이여야 한다는 것이다.

 

변수를 셋팅하는 방법은 아직 고민을 안해봤다..(머..규칙을 만들면..가능할지도...ㅎㅎ)

 

자, 본격적으로 설명을 해 보겠다.

예를 들어, dept_cd 라는 부서코드가 공통코드 테이블에 01 이라는 대표번호로 정의가 되어 있고,

kind 라는 종류(어느 종률까? ㅋ) 를 나타내는 코드 내용이 공통코드 테이블에 02라는 대표번호로 정의가 되어 있다고 보자.

 

이럴 경우, 우린 두 가지 방법으로 dddw를 정의한다.

먼저, dept_cd, kind 컬럼용 dddw를 아규먼트 없이 각자 생성한다. 자동으로 조회시킨다.

두번째는 대표번호를 아규먼트로 하는 dddw를 하나 생성 해놓고, 스크립트에서 getchild() 해서 직접 조회해준다.

 

전자의 경우에는 편하지만, 그 코드수만큼 dddw를 만들어야 한다. 형식이 똑같다면,  자원의 낭비가 될 수도 있다.

이점에 기인해서 후자의 경우를 좀 편하는 하는 방법을 적용한 것이다.

 

dept_cd, kind 컬럼의 태그에 각 각 01, 02만 셋팅해놓는다.

 

이제 공통 조상 윈도우에서는 다음과 같은 함수를 하나 만들어서 open 시에 실행만 시켜주면 된다.

그전에 함수 하나 더 추가

함수명 : stringtokenize

아규먼트 : ref string as_source

                        string as_separator

리턴값 string

integer li_pos
string  ls_retValue

if isnull( as_source ) or IsNull( as_separator ) THEN
 String ls_Null

 SetNull( ls_Null )
 Return ls_Null
END IF

li_pos = Pos( as_source, as_separator )
IF li_pos = 0 THEN
 ls_retValue = as_source
 as_source = ""
ELSE
 ls_retValue = Mid( as_source, 1, li_pos - 1 )
 as_source = Right( as_source, Len(as_source) - (li_pos + Len( as_separator ) -1 ) )
END IF

Return ls_retValue

 

 

함수명 : wf_set_comdddw

아규먼트 : datawindow adw

리턴값 없음

 

DatawindowChild ldwc_child
String ls_objects, ls_col_nm, ls_dddw_name, ls_cd_id
ls_objects = adw.Describe("DataWindow.Objects")
do while true
 // 각 컬럼의 이름을 가져온다.
 if ls_objects = '' then
  exit
 end if
 ls_col_nm = stringtokenize(ls_objects, '~t')
 //해당 컬럼이 dddw 타입이 아니면 패스..
 if adw.Describe(ls_col_nm+".Edit.Style") <> 'dddw' then continue
 ls_dddw_name = adw.Describe(ls_col_nm + ".dddw.name")
 //공통 코드 dddw 가 아니면 패쓰..
 choose case ls_dddw_name
  case 'd_dddw_common' //공통 코드 dddw 명.. 사용자에 따라 다르겠죠? ^^
   //태그값을 읽어서 자동으로 조회시킨다.
   ls_cd_id = adw.Describe(ls_col_nm + ".tag")
   if adw.GetChild(ls_col_nm, ldwc_Child) = -1 then
    Messagebox('Error', 'wf_set_comdddw() , Getchild() 에러')
    exit
   end if
   ldwc_child.setTransObject(sqlca)
   ldwc_child.retrieve(ls_cd_id)
  case else
   continue
 end choose
Loop

 

Posted by 농부지기
,

[ 파워빌더.DDDW - filter.방향키 제어 ]

 

 

dddw row 조건에 따라 filter를 이용해서 제어 하는 부분중 상하키를 이용하여 이동될때 제어하는 예제가

 

까리보이님께서 올려 주신 http://cafe.naver.com/pentaeduclub/942 가 있는데.. 이를 달리 datastore 없이 사용하게 변경해 보았습니다..

 

1. child 필터시 SetValidate 사용

DatawindowChild ldw_child
Long ll_FilteredCount

 

/* 그냥 DatawindowChild  구한 겁니다 */

If uf_getchild ( as_col , ldw_child ) Then

    /* filter 조건을 datacolumn에 Set 합니다. */
    ldw_Child.SetValidate (as_col_code, as_filter )
    ldw_Child.SelectRow ( 0 , False )
    ldw_child.SetDetailHeight( 1, ldw_child.rowcount(), 0)
    /*

        다른 예제를 보면 부정형으로 되어 있는데 여기선 긍정형 입니다. 

        예를 들어 dept_cd 가 '10' 인 자료만 filter 를 할경우 dept_cd ='10' 이죠 긍정형 으로 

    */
    ldw_child.setfilter( as_filter )
    ll_FilteredCount = ldw_child.filter()
    ldw_child.SetDetailHeight( 1, ldw_child.Rowcount(), Long(ldw_child.describe("datawindow.detail.height")))
    ldw_child.setfilter( "" )
    ldw_child.filter( )
    ldw_child.setSort( "#1 A, #2 A" )
    ldw_child.Sort( )
 Return ll_FilteredCount
Else
 Return 0
End If

 

2. uf_setitem ( row , dwo, any )

choose case Mid(this.describe(dwo.name + ".coltype"),1,5)
 case "long", "ulong","real", "numbe"
  messagebox ('setitem',this.SetItem(al_row,String(dwo.name), Long(aa_data)))
 case "doubl"
  this.SetItem(al_row,String(dwo.name), Double(aa_data))
 case "decim" //al
  this.SetItem(al_row,String(dwo.name), Dec(aa_data))
 case "date"
  this.SetItem(al_row,String(dwo.name), Date(aa_data))
 case "datet" //ime
  this.SetItem(al_row,String(dwo.name), DateTime(aa_data))
 case "time"
  this.SetItem(al_row,String(dwo.name), Time(aa_data))
 case "char("
  this.SetItem(al_row,String(dwo.name), aa_data)
 case else
end choose

// itemchanged Event 재 호출

This.event itemchanged( al_row, dwo, String(aa_data))

3. uf_getitem ( row, col, buffer, true or false )

any la_item

choose case Mid(this.describe(as_col + ".coltype"),1,5)
 case "long", "ulong","real", "numbe"
  la_item = this.getItemNumber(al_row, as_col, adwbf_buffer, ab_org)
 case "decim" //al
  la_item = this.getItemDecimal(al_row, as_col, adwbf_buffer, ab_org)
 case "date"
  la_item = this.getItemDate(al_row, as_col, adwbf_buffer, ab_org)
 case "datet" //ime
  la_item = this.getItemDateTime(al_row, as_col, adwbf_buffer, ab_org)
 case "time"
  la_item = this.getItemTime(al_row, as_col, adwbf_buffer, ab_org)
 case "char("
  la_item = this.getItemString(al_row, as_col, adwbf_buffer, ab_org)
 case else
end choose

return la_item

 

4. 제어 함수 만들기 (function name : uf_dropdown , 파레메타는 itemchanged 와 동일합니다.)

datawindowchild adwc_child
 

/* 그냥 DatawindowChild  구한 겁니다 */  
If io_child.uf_getchild( dwo.name, adwc_child ) Then
    Long ll_find, ll_row , ll_idx
 String ls_rule, ls_datacolumn
 // Drop Down Name Get
 ls_datacolumn = Describe(dwo.name+".dddw.datacolumn")
 
 // Column Type 에 따라 입력된 값의 Row Search
 If Mid(adwc_child.describe(ls_datacolumn + ".coltype"),1,5) = 'char(' Then
  ll_row = adwc_child.Find (ls_datacolumn + "='" + data +"'", 1, adwc_child.RowCount())
 Else
  ll_row = adwc_child.Find (ls_datacolumn + "=" + data, 1, adwc_child.RowCount())
 End If
 
 // Column Validate Get
 ls_rule = adwc_child.getvalidate( Integer ( adwc_child.describe( ls_datacolumn +".id") ) )

 // Validate 가 없으면 정상 Return
 If f_snvl ( ls_rule , '' ) = '' Then
  Return 0
 End If
 // Column Type에 따라 Validate 검증
 If Mid(adwc_child.describe(ls_datacolumn + ".coltype"),1,5) = 'char(' Then
  ll_find = adwc_child.Find (ls_datacolumn + "='" + data +"' and " + ls_rule , 1, adwc_child.RowCount())
 Else
  ll_find = adwc_child.Find (ls_datacolumn + "=" + data +" and " + ls_rule , 1, adwc_child.RowCount())
 End If

 If ll_find = 0 Then
  If KeyDown(KeyUpArrow!) Then
   If ll_row > 1 Then
    //하단으로 부터 동일 Rule자료 찾기
    For ll_idx =  ll_row - 1 To 1  STEP -1
     ll_find = adwc_child.Find (ls_rule , ll_idx, ll_row - 1)
     If ll_find > 0 Then Exit
    Next
   Else
    // 이전 값으로 대체
    This.Post uf_setitem (row,  dwo, uf_getitem( row, dwo.name, Primary!, True) )
    Return 0
   End If
  Else
   // 현 위치 보다 아래에서 찾기
   ll_find = adwc_child.Find (ls_rule , ll_row + 1, adwc_child.RowCount())
  End If
  
  If ll_find > 0 Then
   adwc_child.SelectRow(0, False)
   adwc_child.SetRow(ll_find)
   adwc_child.ScrollToRow(ll_find)
   adwc_child.SelectRow(ll_find, True)
   If Mid(adwc_child.describe(ls_datacolumn + ".coltype"),1,5) = 'char(' Then
    This.Post uf_setitem (row,  dwo, adwc_child.GetItemString(ll_find,ls_datacolumn) )
   Else
    This.Post uf_setitem (row,  dwo, adwc_child.GetItemNumber(ll_find,ls_datacolumn))
   End If
   Return 0
  Else
   // 이전 값으로 대체

   /* column datatype 에 따라 Setitem 해 준겁니다 */
   This.Post uf_setitem (row,  dwo, uf_getitem( row, dwo.name, Primary!, True) )
   Return 0
  End If
 Else
  // Validate 정상 Return
  Return 0
 End If
Else
 Return 0
End If

Return 0

 

5. event 에 반영 (itemchanged)

//Drop Down 처리

uf_dropdown ( row, dwo, data )

Return 0

 

6. 실제 사용

    ---> 적용하려는 dw constructor에서 filter 초기화 

         --> drop down click 없이 바로 해당컬럼에서 상/하 키 사용시 처리 위함

   --->  해당 Column에서 pbm_dwndropdown event 발생시 child filter

   ---> 만약 filter 조건이 변경할 경우 변경되는 column itemchanged 에서 filter 재설정

         --> drop down click 없이 바로 해당컬럼에서 상/하 키 사용시 처리 위함

 

공통에 반영되어 있어 이 부분만 추출하여 별도로 만들기가 어렵네요.. 쩝  소스로 못올려 죄송합니다..

☞  

 

Posted by 농부지기
,

[ 파워빌더.DDDW - filter.sort ]

 

 

is_stgu = dw_acc.getitemstring(1,'a')

 

dw_acc.getchild('b', idwc_stcd)

idwc_stcd.settransobject(sqlca)

idwc_stcd.retrieve()

 

idwc_stcd.SetFilter( " gbcd = '" + is_stgu + "' and itag = '0'" )

idwc_stcd.Filter()

idwc_stcd.SetSort('stcd')

idwc_stcd.Sort()

 

Posted by 농부지기
,

[ 파워빌더.DDDW - 디스플레이 된값을 가져오는 함수  ]

 

☞   

  /*
 string gf_dddw_data( datawindow ad_datawindow, long al_row, string as_column_name )
 dddw에 디스플레이 된값을 가져오는 함수이다.
 반환은 String값이며 DataWindow와 Row 값, 컬럼의 이름을 주면 된다.
*/
any la_any
string ls_dispcol, ls_codecol, ls_coltype
long ll_frow
datawindowchild dwc
la_any = ad_datawindow.GetItemString(al_row, as_column_name)
ad_datawindow.getchild(as_column_name, dwc)
ls_dispcol = ad_datawindow.describe(as_column_name + ".DDDW.DisplayColumn")
ls_codecol = ad_datawindow.describe(as_column_name + ".DDDW.DataColumn")
ls_coltype = dwc.describe(ls_codecol + ".coltype")
if pos(ls_coltype,'char') > 0 or pos(ls_coltype,'date') > 0 or pos(ls_coltype,'datetime') > 0 then
 ll_frow = dwc.find(ls_codecol + " = '" + string(la_any) + "'", 1, dwc.rowcount())
else
 ll_frow = dwc.find(ls_codecol + ' = ' + string(la_any), 1, dwc.rowcount())
end if
if ll_frow > 0 then
 ls_coltype = dwc.describe(ls_dispcol + ".coltype")
 if pos(ls_coltype,'(') > 0 then ls_coltype = left(ls_coltype,pos(ls_coltype,'(') - 1)
 choose case ls_coltype
  case 'decimal'
   la_any = dwc.getitemdecimal(ll_frow,ls_dispcol)
   return string(la_any, "#,###")
  case 'number', 'long'
   la_any = dwc.getitemnumber(ll_frow,ls_dispcol)
   return string(la_any, "#,###")
  case 'char'
   la_any = dwc.getitemstring(ll_frow,ls_dispcol)
   return string(la_any)
  case 'date'
   la_any = dwc.getitemdate(ll_frow,ls_dispcol)
   return string(la_any, "YYYY-MM-DD")
  case 'datetime'
   la_any = dwc.getitemdatetime(ll_frow,ls_dispcol)
   return string(la_any, "YYYY-MM-DD HH:MM:SS")
 end choose
end if
return ""

Posted by 농부지기
,

[ 파워빌더.DDDW - 에 존재하는 컬럼값 얻기  ]

 

 

☞   

 

 
 contest_seq     = go_dddw.of_sub_column_value(dw_k4, 'contest_yyseq', 'contest_seq', 'number');

 contest_name    = Trim(dw_k4.Describe("Evaluate('LookUpDisplay(contest_yyseq)', 1)"))

Posted by 농부지기
,

[ 파워빌더.DDDW - 처리 방법  ]

 

1. dddw 속성 설명
    . Edit - AutoRetrieve : 존재하는 datawindow가 Retrieve 되면서 자동으로 dddw도 Retrieve된다.
                            만약, argument가 존재 하는 dddw는 항상 argument를 달라고 pop_up창이 뜬다.
           - V ScrollBar  : dddw가 펼처 지면서 상/하 scroll이 발생한다.

   . Edit - 보통 V ScrollBar 만 체크 하고 개발한다.

2. dddw를 source상에서 Retrieve 하기
   DataWindowChild ldwc_name
   dw_d1.GetChild('컬럼명', ldwc_name)
   ldwc_name.SetTransObject(SQLCA)
   ldwc_name.Retrieve('arg1', 'arg2', ...)


3. dddw의 code가 아닌 display 된 값 얻기
   ls_name = Trim(dw_k1.Describe("Evaluate('LookUpDisplay(컬럼명)', row)"))

    //참고, 위 row는 : Grid상태에서의 row 이다.

4. dddw의 내부 컬럼 값 얻기
   DataWindowChild ldwc_name
   dw_d1.GetChild('컬럼명', ldwc_name)
   li_sel_row = ldwc_name.GetSelectedRow(0)
   ls_value   = Trim(ldwc_name.GetItemString(li_sel_row, 'code 나 name이 아닌 다른 컬럼명'));

5. dddw에ㅓ Filter 적용하기 : ldwc_name.SetFiler("컬럼명 = 'a'")
6. dddw에서 한줄 삽입       : ldwc_name.InsertRow(1)

   ls_name    = Trim(dw_k1.Object.contest_name.ldwc_name.Object.game_name[li_sel_row])

Posted by 농부지기
,

[ 파워빌더.DataWindow - Error Log 파일 생성 ]

 

dw의 DB Error 시  Err Log를 기록하는 팁입니다..

dw의 조상오브젝트에 넣으면 편하겠죠..

 

<dw의 dberror 이벤트에..>

 

//This.ScrollToRow(Row)

 

Long  lFileNum

 

IF 개발자유저이면.. THEN
 lFileNum = FileOpen('c:\dberror.txt', LineMode!, Write!, LockWrite!, Append!)
 FileWrite(lFileNum, String(today(), "yyyy.mm.dd hh:mm:ss") + ":" + 사용자ID + "/" + 사용자명 + " (Error Code : " + string(sqldbcode) + ")~n~n" + sqlsyntax + "~n~n" + sqlerrtext)
 FileClose(lFileNum)
END IF

//오라클일때... sqlca.DBParm 에.. DisableBind=1 추가하면 sqlerrtext 가 자세하게 나온다네요..

Posted by 농부지기
,

[ 파워빌더.DataWindow - 내부 Object를 배열에 담기  ]

 

☞   

 

dw 내의 모든 오브젝트들의 이름을  string 배열에 넣어 주는 함수 입니다..

 

/* f_GetObjects( dwWhich, ref  sReturn[] ) */

 

Long  lFind
String sCol, sObjects
  
sObjects = dwWhich.Describe('DataWindow.Objects')
sObjects = sObjects + '~t'

DO
 lFind = Pos(sObjects, '~t')
 
 IF lFind > 0 THEN
  sCol = Left(sObjects, lFind - 1)
  
  sReturn[UpperBound(sReturn[]) + 1] = sCol

  sObjects = Mid(sObjects, lFind + 1)
 END IF
LOOP WHILE lFind > 0

Posted by 농부지기
,

[ 파워빌더.DataWindow - 동적 버튼 생성 ]

 

☞   

 

ls_modify = "create button(band=Background"
ls_modify += " x='0' y='0'"
ls_modify += " height='150'"
ls_modify += " width='300' "
ls_modify += " name=b_new1 "
ls_modify += ' text="자동" '
ls_modify += ' pointer="HyperLink!" '
ls_modify += " )"
dw_1.Modify(ls_modify)

이렇게 하면 버튼이 하나 만들어집니다.

 

그리고 이번튼이 눌렸을때 작동하는 이벤트는

DW ButtonClicked Event에서

choose case dwo.name
 case 'b_new1'
  messagebox(parent.title, '안녕' )

 Case 'b_Select'

   gf_GetSawonList( w_sawonlist, '부장', '', '')

 :

 :
end choose

 

이렇게 만들어둔 함수를 호출합니다.

 

현재 동적으로 이벤트를 만드는 방법은 모르겠습니다.(없는지 있는지도 잘모르겠습니다.)

 

Posted by 농부지기
,