파워빌더 팁1(퍼옴)

 
파워빌더로 프로그램 수정 도중에 막히는 부분이 있어 검색하다가 발견한 포스팅.
마구 퍼담는 블로거들을 보면서 차라리 안쓰고 말지 했었는데 저도 결국은 퍼오네요.
퍼감을 허락해주신 “주니’s” 님께 감사드립니다. (__)

파워빌더 팁1
■각종 resource file(bmp, ini, dll, object)의 path 설정
1. project 생성시(exe file 생성시) resource file name 정의
text edit로 resource file에 대한 path를 기술한후 저장한다.
ex)  c:\mis\ne\picture\aaa.bmp
c:\mis\ne\picture\bbb.bmp
c:\mis\ne\ini\ne.ini
:
저장된 파일을 resource file name 에 기술한후 실행한다.
이 방법은 실행파일이 실행시 해당파일의 path를 이용해 직접 access함으로 실행
속도가 빠른 장점이 있지만, 항상 client pc에는 resource file에 정의된 path로
고정되어 설지되어야 하는 단점이 있다.
2. 절대path나 상대path를 이용
picture button을 예로 들면 해당 bmp file의 절대path(c:\gmis\cine\aaa.bmp)
나 상대path(..\picture\aaa.bmp)로 설정한후 install program 생성시 항상 그 위
치에 생성되도록 한다. 그리고 autoexec.bat에 path를 추가한다.
3. windows시스템의 reg.dat 파일 이용
windows의 reg.dat에 기록하여 해당파일 실행시 특정 디렉토리가 참조되도록 설정
picture button에는 bmp file name만 기술 (aaa.bmp)
install program 생성시 bmp file에 대한(또는 기타 dll file emd) 각각의 콤포넌
트를 기술한후 add to path에 체크하고, 참조하는 실행파일을 선택한다.
이렇게하면 프로그램 설치시 각종 resource들이 어디에 설치되더라도 path가
windows의 reg.dat에 기록되어 해당 실행파일 기동시 path가 참조된다.
저같으면 3번의 방법을 이용하겠습니다.
■picture button에 tooltip보기(마우스 위치시 text help)
1. picture button의 mousemove event의 script에 작성
//—————– Tool Tip ———————–//
//st_tool_tip.resize(w,h)
st_tool_tip.visible=true
st_tool_tip.text=”신규”
st_tool_tip.x=this.x
st_tool_tip.y=this.y+this.height+1
//—————– Tool Tip ———————–//
2. windows의 mousemove event
st_tool_tip.visible=false
■DataWindow에서 bmp를 사용치 않고 간단한 image 나타내기
datawindow에서 bmp를 사용치 않고 wingdings font를 이용해서 간단한 이미지를 나
타낼 수 있다.
multirow처리시 체크, x 표시등으르 나타낼때 사용
예제) delete 될 row는 x표시, update될 row는 체크표시를 할때
1. datawindow의 font를 wingdings로 선택한다.
2. datawindow에서 computed column를 만들고 내용에
if(flag=’U’, ‘□, if(flag=’D’, ‘□, “”))
라고 작성
여기서 ‘□표시는 alt키를 누른후 숫자판에서 0252(체크표시),
0251(X표시)를 입력하면 된다.
■Power builder 5.0에서 한영토글
1.개요
Power Builder Aplication을 작성하다보면  조회나 입력을 위해 user가 입력하는
부분이 많은데 이때 입력하는 문자가 영문인지 한글인지에 따라 매번 한/영 key를
눌러주어야 하는 번거로움이 있다.
이러한 번거로움을 없애기 위해 사용자가 매번 한/영 키를 누르지 않고 입력하려
는 부분으로 focus가 가면 입력란의 성격에 따라 한글 또는 영문으로 자동 토글되게
하는 방법이다.
2.세부기능
기본적으로 “pbwin32.dll”이라는 dll을 사용한다.
이 파일을 윈도우의 Grobal External Funtion에 선언하고 토글이 일어날고자하는
Edit Object의 Getfocus Event에서 호출하는 방법으로 사용한다.
그러므로  한/영 토글을 위해서는 우선 “pbwin32.dll” 이라는 파일이 있어야 하며
배포할 때도 빼놓지 않도록 주의한다. (인터넷이나 유니텔에서 구하기)
3.Prototyping
① “pbwin32.dll”을 적당한 곳에 copy해 놓는다.
② Window의 Declare Menue 의 Grobal External Funtion 에  다음과 같이 선언한다.
/*Declare Grobal External Functions
FUNCTION INT f_toggle_kor(int hwin ) library “pbwin32.dll”
FUNCTION INT f_toggle_eng(int hwin) library “pbwin32.dll”
③ 한영 토글하는  Function Object 작성한다.
Function:set_eng /*영문으로전환*/
f_toggle_eng(Handle(parent))
return 0
Function:set_han/*한글로전환*/
f_toggle_kor(Handle(parent))
return 0
④ Window 의 SingleLineEdit Object 의 “Getfocus Event” /”LoseFocus Event”
(DataWindow의 경우는 “ItemFocusChanged” Event) Script에
set_eng()   또는   set_han()
라고 기술한다.
■PB에서의 이벤트 제어
1. 개요
이벤트는 시스템에 어떤 일이 일어났는지를 프로그램에게 알려주는데 사용하는 방
식이다. 윈도우에서는 모든 프로그래밍의 기본으로 이 이벤트구동 방식을 사용하고
있다. 파워빌도에는 기본적인 윈도우 이벤트가 제공되며, 또한 사용자 자신의 이벤
트도 정의할 수 있게 하고 있다.
이제 Event 발생(Trigger)과 event 기록(Post)의 차이점과 기능을 알아본다.
파워빌더는 TriggerEvent()함수와 PostEvent()함수를 제공한다. 이것들은 이벤트
를 프로그램적으로 발생시킬때 사용한다.  공통점은 요청된 스크립트를 수행한다는
점이고, 차이점은 수행시점이 다르다는 점이다.
2. 세부기능
1) TriggerEvent() 함수
이 함수는 목표가 되는 이벤트에 즉시 컨트롤을 보내는 함수이다.
원리는 간단하다. 만약 어떤 스크립트상에 이 함수가 포함되어 있을경우, 이
벤트는 트리거되고 전체적인 동작은 동시에 동기적으로 이루어지게 된다.
따라서 화면상으로 보기에는 수행속도가 느리게 보여지게 된다.
또한, 이 함수에는 두개의 파라미터를 지정할수 있다.
형태 1 —  둘다 long 형의 integer
형태 2 —  한개의 long  integer, 한개의 string
예) pb_1.TriggerEvent(“ue_test”, ll_word, ls_temp)
2) PostEvent() 함수
이 함수가 호출되면 파워빌더는 지정된 이벤트를 이벤트 큐의 끝에 추가하고
최초 스크립트의 실행을 계속한다. 만약 윈도우의 Open Event에서 어떤 기능
이 주어졌을때, 이 함수는 원래의 스크립트 실행을 기다린다. 한편 큐에 대기
중인 모든 이벤트가 처리되면 파워빌더는 마지막으로 postevent()에 의해 큐
에 저장되었던 이벤트를 받아서 처리한다.
이 방식의 결과는 윈도우의 open스크립트가 빨리 수행되어진다는 점에서 상
당히 빠른 수행속도를 보여줄 수 있다. 즉, 이 방식은 비동기적으로 이벤트를
활성화시킨다.
위에서와 마찬가지로 postevent()함수도 두개의 파라미터를 가지고 이벤트
간 상호 통신할 수 있다.
형태 1 —  둘다 long 형의 integer
형태 2 —  한개의 long  integer, 한개의 string
예) pb_1.PostEvent(“ue_test”, ll_word, ll_temp)
3) 파라미터 리턴
두함수에 파라미터를 지정하면 파워빌더는 데이터항목을 메세지 오브젝트의
WordParm과 LongParm속성에 복사된다. 전달받는 스크립트는 이러한 속성을 단
순 할당을 통해서 변수 값으로 전달받는다.
3.Prototyping
1) TriggerEvent()
cb_OK.TriggerEvent(Clicked!)
Parent.TriggerEvent(“cb_exit_request”)
cb_OK.TriggerEvent(“cb_exit_request”, ls_str)
파라미터를 받는 이벤트 쪽 스크립트
string PassedString
PassedString = String(Message.LongParm, “address”)
2) PostEvent()
cb_OK.PostEvent(Clicked!)
Parent.PostEvent(“cb_exit_request”)
Parent.PostEvent(“cb_exit_request”, 455, 0)
파라미터를 받는 쪽
integer numarg
numarg = Message.WordParm
■어플리케이션이 한번만 실행 되게…
우리 시스템이 두번 실행 되는걸 방지하고자 한번 알아 보았습니다.
—————————————————————
Global Variable에 선언을 하나 합니다.
UINT gui_hMutex
External Function에 선언을 합니다.
FUNCTION UINT CreateMutex ( ULONG lpsa, BOOLEAN fInitialOwner, &
STRING lpszMutexName ) LIBRARY “Kernel32.DLL” ALIAS FOR “CreateMutexA”
FUNCTION ULONG GetLastError ( ) LIBRARY “Kernel32.DLL”
FUNCTION BOOLEAN ReleaseMutex ( UINT hMutex ) LIBRARY “Kernel32.DLL”
Application Object의 Open Event에 다음과 같이 기술 합니다.
gui_hMutex = CreateMutex ( 0, TRUE, “PBAPP_MUTEX” )
IF GetLastError() = 0 THEN
Open(w_main_frame)
ELSE
MessageBox(“!”, “Already Running!”)
HALT
END IF
Application Object의 Close Event에 다음과 같이 기술 합니다.
ReleaseMutex ( hMutex )
CreateMutex()라는 API는 시스템 전체에 유일한 자물쇠를 만든다 생각하면 됩니다.
위에 예를 든 “PBAPP_MUTEX”가 바로 자물쇠의 이름이 되는겁니다.
이 이름은 임의대로 주어도 상관 없을 것이고, 전체적인 로직은 간단합니다.
마지막으로 EXE화일을 만든후 실행해 보시면 성공여부를 알수 있습니다.
■Date Scroller
1.개요
날자 처리를 하는 화면에서 년도, 월, 일자를 변화시킬때 원하는 부분을 OBJECT가
생성될때 선택 되어지게 하는 기법
2.세부기능
(1). Constructor Event
uis_jeonpyo_date = STRING(TODAY())
this.triggerevent(‘ue_input_date’)
(2). ue_input_date
em_date.text = uis_jeonpyo_date
em_date.SelectText(9,2)
(3). VScrollBar
integer li_subt_day_down, li_position_down
integer li_year_down, li_month_down, li_day_down
date    ld_date_down
em_date.SetFocus()
li_position_down = em_date.Position()
li_day_down      = integer(Right(em_date.text, 2))
IF li_position_down 〈 6 THEN
li_year_down  = integer(Left(em_date.text,4)) – 1
li_month_down = integer(Mid(em_date.text, 6, 2))
ld_date_down = date(li_year_down, li_month_down, li_day_down)
em_date.text = String(ld_date_down)
em_date.SelectText(1, 4)
ELSEIF (li_position_down 〉 5) and (li_position_down 〈 9) THEN
IF IsDate(em_date.text) THEN
li_subt_day_down = (-1) * uf_days(-1)
em_date.text = String(Relativedate(Date(em_date.text), &
li_subt_day_down))
ELSE
em_date.text = String(Today())
END IF
em_date.SelectText(6, 2)
ELSE
IF IsDate(em_date.text) THEN
em_date.text = String(Relativedate(Date(em_date.text), -1))
ELSE
em_date.text = String(Today( ))
END IF
em_date.SelectText(9, 2)
END IF
■Drag & Drop
1.개요
윈도우 프로그램에서 주로 사용하는 기법인 DRAG & DROP 기법 활용예
2.세부기능
(1). 원본 오브젝트에 User Event 를 만든다.
-Event Name :  myclick
Event ID    :  pbm_lbuttondown
(2). 원본 오브젝트에 만든 myclick Script
this.drag(Begin!)
this.dragicon = “c:\pb50\row.ico”   // 손가락 CION ☜
(3). 대상 오브젝트의 DragDrop Event
pb_1.triggerevent(clicked!) 즉 자신이 원하는 Event를 발생시킨다.
※ MicroHelp 처리를 원하면
– DragEnter : w_acmd_frame.SetMicroHelp(“~~~처리를 합니다.”)
– DragLeave : w_acmd_frame.SetMicroHelp(“”)
※ Picture가 변하는 효과를 원한다면
– DragEnter Event : pb_1.picturename = “c:\…..\1.bmp
– DragLeave Evnet : pb_1.picturename = “c:\…..\2.bmp
■ItemError Event
1.개요
데이터윈도우에서 수치컬럼에 입력할 데이터의 Validation check를 프로그래머가
직접 통제
2.세부기능
테이타 윈도우 컬럼에서 NUMBER 타입의 경우 자료를 수정하거나 입력할때, Del 키
를 사용하고 저장하거나, 잘못된 타입의 데이타를 입력하고, 저장하면 (혹은
ItemChange 를 하면) 파워빌더 스스로 Validation 체크를 한다.
이것을 막는 방법은 데이타윈도우의 ItemError event 에서
0 (Default) Reject the data value and show an error message box.
1 Reject the data value with no message box.
2 Accept the data value.
3 Reject the data value but allow focus to change.
■ShareData 함수
1.개요
ShareData 함수는 둘 또는 그 이상의 데이터윈도우 사이에서 데이터를 공유하기
위해 파워빌더 스크립트에서 사용되며 데이터를 한 데이터윈도우에서 다른 데이터윈
도우로 옮기는데 드는 힘든 작업을 피할 수 있게 해준다.
2.세부기능
1) 공유의 조건 : 두개의 데이터 윈도우 즉.dwprimary(기본데이타윈도우)와
dwsecondary(종속데이타윈도우)는  데이터 소스 리절트 셋이 서
로 맞아야 한다.
2) 공유의 이점 : 데이터 윈도우 공유의 이점으로는 서로 다른 포맷을 사용할 수
있다는 것이다. 즉 tabular 와 free form 형식, display와
printed 보고서 형식, 심지어는 grid와 graph 사이에서도 공유될
수 있다.
3.Prototyping
1) ShareData()함수
dw_sheet.SetTransObject(SQLCA)  //기본 dw를 위해 트랜잭션 객체 설정//
dw_sheet.ShareData(dw_report)   //기본 dw와 종속dw 공유//
dw_report.print()               //종속 dw 프린트하기//
2)ShareDataOff() 함수
w_cine_info.dw_sheet.ShareDataOff()   //기본 dw의 데이터 공유 제거//
3)드롭다운 자식 데이터윈도우 공유
datawindowchild dwc_sheet, dwc_report  //datawindowchild 타입으로 2개의
//임시 변수 정의
dw_sheet.SetTransObject(sqlca)         //기본 dw를 위해 트랜잭션 객체 설정
dw_sheet.ShareData(dw_report)          //기본 dw와 종속 dw 공유
dw_sheet.dwGetChild(“employee_department”,dwc_sheet)
//dw_sheet를 위한 드롭다운
//datawindowchild를 구한다.
dw_report.dwGetChild(“employee_department”,dwc_report)
//dw_report를 위한 드롭다운
//datawindowchild를 구한다.
dwc_sheet.ShareData(dwc_report)        //자식 데이터윈도우 공유
dw_report.print()                      //종속 dw 프린트하기
4.Issue
1)둘 이상의 종속 dw를 공유하기 위해서는 각각의 종속dw에 함수를 call해주어야
한다.
2)Crosstab 데이터윈도우는 종속dw가 될 수 없다.
3)데이터가 공유될 때 드롭다운데이타윈도우는 자동으로 공유되지 않는다.
■스크롤된 위치가 마지막라인인지 확인하려면
Q) 데이터윈도우를 스크롤하다가 마지막 라인까지 스크롤되었을 경우 서비스를 다시
Invoke하여 남아있는 데이터를 가져오려고 합니다. 마지막라인까지 스크롤되었는지
를 알려면 어떻게 할까요?
A) 일반 이벤트로는 나와있지 않다
화면에서 스크롤바를 클릭할때마다 윈도우의 pbm_vscroll 이벤트가 발생하는데
이를 이용하면 됩니다
먼저 윈도우의 Declare -> User Events 에 vscroll이벤트를 첨가시켜주세요
event name              event id
————-          ————–
vscroll                pbm_vscroll
그러면 스크립트를 작성하는 화면 상단의 Select Event에 위에서 첨가시킨
vscroll 이벤트가 보입니다
그 이벤트의 스크립트를 다음과 같이 작성하시면 됩니다
string s1, s2
s1 = dw_1.Describe(“Datawindow.VerticalScrollPosition”)
s2 = dw_1.Describe(“Datawindow.VerticalScrollMaximum”)
if s1 = s2 then
//마지막라인까지 스크롤되었을때 하고자 하는 작업의 스크립트
end if
참고로 verticalscrollposition은 데이터윈도우의 현재 스크롤바의 위치이고
VerticalScrollMaximum은 최대한 스크롤할 수 있는 위치입니다
(데이터가 많으면 커지겠죠)
■DataWindow의 data를 조건입력으로 선별조회를…
FUNCTION KEY PF4를 이용한 선별 조건기능을 파워빌더에서 구현하였습니다.
구현한 내용을 간단하게 설명하면
[글로벌 변수에 datawindow type으로 변수(대상 datawindow)와
string type으로 변수를 선언(return될 검색조건 string)하여
첨부한 pbl의 window를 open합니다.]
1.  Global Variables :
datawindow gx_cur_dw_name
string     gx_filter_cond
2.  원하는 event script :
gx_cur_dw_name = dw_1
open(w_miv_filter)
if gx_filter_cond 〈〉 “” then
dw_1.SetFilter(gx_filter_cond)
dw_1.Filter()
else
return
end if
■External Datawindow 의 활용( TXT –> TABLE 반영)
1. HOST 의 TABLE에서 DATA를 DOWN-LOAD받은후 엑셀에서 필드를 TAB또는 COMMA로구
분 하여 TXT File 형태로 저장한다.
2. 아래와 같은 Window 를 만듭니다.
3. 다음과 같이 data source가 External인 DataWindow를 만듭니다.
( Data source 가  꼭 External이 아니더라도 차이는 없다 )
4. 다음과 같이 Instance 변수를 선언한다.
String Pathname
1) SELECT File button 의 SCRIPT
string filename,Pathname,i_bmp
int rc
rc = GetFileOpenName( ‘Select TXT’,&
Pathname,filename,’txt’,’BitMap(*.txt),*.txt’)
IF rc = 1 THEN
dw_1.reset()
dw_1.ImportFile(Pathname)
END IF
2) UPDATE Button SCRIPT
uo_3d_meter.uf_set_position (0)
ii_interval = 2
string i_acct1,i_acctnm1,i_acct2, i_acctnm2
int y
FOR y = 1 TO  dw_1.rowcount()
i_acct1  = dw_1.getitemstring(y,1)
i_acctnm1  = dw_1.getitemstring(y,2)
i_acct2 = mid(trim(i_acct_id),1,8)
i_acctnm2 = mid(trim(i_acct_nm),1,30)
INSERT INTO aacacctt(acct,acctnm)
values(:i_acct2,:i_acctnm2);
IF SQLCA.SQLCODE = 0 THEN
commit;
sle_text.text = ‘현재 작업중 이오니 잠시 기다려 주십시오 …. ‘
Timer (ic_timer_interval)
ELSE
rollback;
return
END IF
NEXT
Timer (ic_timer_interval)
*  3 TIER로 구현하려면
DATA ACCESS 부분 (위의 INSERT 부분을 XPL로 CODING 하면됨)
■vscroll event 를 활용한 sample
[VSCROLL EVENT]
1) 설정
– f_get_request(), f_fill_response(), invoke  user object,
– new_code(local) : rtn_code = 0(정상), rtn_code = 100(마지막건),
rtn_code = 1003(no statement parse)
– array수를 100으로 잡고 처음 open시 한번 invoke를 발생시키고, scroll var를
누르면서 데이터가 마지막 record에 도달했을 때 다음100 건을 가져온다.
최대건수 1000건이상은 pc로 가져올 수 없도록 제한한다.(PC MEMORY를 고려하
여 임의값을 결정)
– INSTANCE VARIABLE
integer old_code = 0
integer row_cnt = 1
integer last_cnt = 1
integer rsp_chk = 1
string   last_val
string   new_msg
2) input
– gbn =  ‘A’
– input_value = ‘M19%’
– last_value = input_value
– open 시 reset()을 넣어주면 vscroll이 자동으로 한번 실행되므로 주의한다.
– 첫번째 INVOKE시 last_value의 설정
처음 input 값은 사용자가 줄 수도 있고 안줄 수도 있다. 그리고 해당값을
like로 조회하므로 얼마의 값이 들어올지 모른다. 따라서 처음 invoke 시는 사
용자가 넣어준 값에 무조건 ‘Z’나 ‘0’을 더하여 넘겨준다.
SQL의 ORDER BY가 오름차순인가 내림차순인가에 따라 오름차순이면 ‘0’
내림차순이면 ‘Z’를 넣어 준다. (단. 입력값이 영문자나 숫자여야한다)
– 다음 INVOKE시 last_value의 설정
SELECT 한값중 마지막값을 넣어준다.
3) SQL
select lc_no, import_req_no, offer_no, offer_po_no
from mimof01t
where lc_no like :input
and lc_no 〈 :last_key_value
order by lc_no desc
4) vscroll event
int rc, last_row
string s1, s2
uo_mim00ofd mim00ofd
datawindow dw
dw = dw_sel_offer
If rsp_chk = 0 Then
return
End If
s1 = dw.Describe(“DataWindow.VerticalScrollPosition”)
s2 = dw.Describe(“DataWindow.VerticalScrollMaximum”)
If s1 = s2 Then
If old_code = 100 Then
MessageBox(“알림”,”마지막자료입니다.”)
return
End If
rsp_chk = 0
SetPointer(HourGlass!)
If old_code = 0 Then
If row_cnt 〉= 1000 Then
MessageBox(“알림”,”1000건이상의 데이터를 가져올 수
없습니다.”)
return
End If
rc= f_mim00ofd_fill_request()
If rc 〈〉 0 Then
return
End If
mim00ofd = create uo_mim00ofd
rc = mim00ofd.Invoke(req_mim00ofm , rsp_mim00ofm)
If rc 〈〉 INVOKE_SUCCESS Then
SetPointer(Arrow!)
MessageBox (“Error”, “Service Call failed. ” +
session.GetError())
Return
End If
rc = f_mim00ofd_get_response()
If rc 〈〉 0 Then
MessageBox(“알림”,trim(rsp_sel_offer.msg))
return
End If
rsp_chk = 1
Choose Case rsp_mim00ofm.gbn[1]
Case ‘A’
last_val =
‘~”+Trim(rsp_mim00ofm.lc_no[last_cnt].lc_no)+’~”
Case ‘B’
last_val =
‘~”+Trim(rsp_mim00ofm.import_req_no[last_cnt].import_req_no)+’~”
Case ‘C’
last_val =
‘~”+Trim(rsp_mim00ofm.offer_no[last_cnt].offer_no)+’~”
Case ‘D’
last_val =
‘~”+Trim(rsp_mim00ofm.offer_po_no[last_cnt].offer_po_no)+’~”
End Choose
End If
End If
SetPointer(Arrow!)
5) f_fill_request()
req_mim00ofm.gbn = rsp_sel_offer.sel
req_mim00ofm.var_no = rsp_sel_offer.input
req_mim00ofm.last_no = f_padd_string(last_val,20)
return 0
6) f_get_response()
integer        row, new_code, new_cnt
decimal        temp_var_decimal
dataWindow     dw
dw = dw_sel_offer
row = 1
new_code = f_from_mxdecimal(rsp_mim00ofm.rtn_code, 0,”UN”)
new_cnt  = f_from_mxdecimal(rsp_mim00ofm.rtn_cnt, 0,”UN”)
If new_code = 1003 Then
rsp_sel_offer.msg = f_padd_string(“No Statement Parse !!!”,80)
return -1
ElseIf new_code = 100 Then
If new_cnt = 0 Then
rsp_sel_offer.msg =
f_padd_string(“조건에 맞는 정보가 없습니다.”,80)
return -1
End If
last_cnt = new_cnt
ElseIf new_code = 0 Then
last_cnt = 100
Else
rsp_sel_offer.msg = f_padd_string(“DATA BASE ERROR !!!”,80)
return -1
End If
For row = 1 to  last_cnt
dw.insertrow(0)
dw.SetItem(row_cnt, “row_no”, row_cnt)
dw.SetItem(row_cnt, “lc_no”, Trim(rsp_mim00ofm.lc_no[row].lc_no))
dw.SetItem(row_cnt, “import_req_no”, Trim(rsp_mim00ofm.
import_req_no[row].import_req_no))
dw.SetItem(row_cnt, “offer_no”, Trim(rsp_mim00ofm.offer_no[row].
offer_no))
dw.SetItem(row_cnt, “offer_po_no”, Trim(rsp_mim00ofm.
offer_po_no[row].offer_po_no))
row_cnt = row_cnt + 1
Next
old_code = new_code
return 0
■mousemove event에서 text display 함수
[MENU ICON TEXT DISPLAY MODULE]
1) mousemove event
– script : f_tooltip_text(‘조회’,pb_query,st_tooltip)
– 조회 : text 명
– pb_query : picture buton object name
– st_tooltip : statictext object name
2) f_tooltip_text(pcase,pbuton,tooltip)
tooltip.resize(100 + len(pcase)*13,65)
tooltip.visible = true
tooltip.x = pbuton.x
tooltip.y = pbuton.y + pbuton.height + 10
if tooltip.text 〈〉 pcase  then
tooltip.text = pcase
end if
return 0
■click envent(click,shift+click,ctrl+click) function 활용
[F_MULTI_SELECT_ROW(click,shift+click,ctrl+click)]
1) datawindow의 click event(old_cRow는 window의 instance variable)
datawindow dw
dw = dw_selpo
old_cRow = f_multi_select_row(old_cRow,dw)
2) f_multi_select_row(old_cRow,dw)
Long  i,cRow,sRow,lRow
If dw.GetClickedRow() 〈〉 0 Then
If KeyDown(KEYSHIFT!) Then
dw.SetRedraw(False)
dw.SelectRow(0,False)
sRow = dw.GetClickedRow()
If old_cRow 〈 sRow Then
For i = old_cRow to sRow
dw.SelectRow(i, TRUE)
Next
ElseIf old_cRow 〉 sRow Then
For i = sRow to old_cRow
dw.SelectRow(i, TRUE)
Next
End If
dw.SetRedraw(True)
lRow = old_cRow
ElseIf KeyDown(KEYCONTROL!) Then
sRow = dw.GetClickedRow()
If dw.IsSelected(sRow) Then
dw.SelectRow(sRow, FALSE)
Else
dw.SelectRow(sRow, TRUE)
End If
lRow = sRow
Else
cRow = dw.GetClickedRow()
dw.SelectRow(0, FALSE)
dw.SelectRow(cRow, TRUE)
lRow = cRow
End If
End If
return lRow
■Activating Another Running Application
Use this method to activate another application that is already running:
1.Declare two local external functions:
Function uint Findwindow(long class, REF string the_name) library “user.exe”
Function BOOLean ShowWindow(int hwnd, int nCmdShow) library “user.exe”
2.Write a script like the following:
string caption
int hwnd
boolean result
caption = “Microsoft Excel” //Title Bar Text of Window to find
hwnd = FindWindow(0,caption)
IF hwnd〈〉0 THEN
result = ShowWindow(hwnd, 1) //Brings window to active state
END IF
■Child window의 특정값을 Parent Window로 넘길때..
Parent Window와 Child Window를 함께 사용할 경우,
Child Window의 Data를 Parent Window로 넘길 때 방법…
(Child Window의 특정값을 Parent Window의 Datawindow에 뿌릴 경우)
(Parameter가 하나일 경우)
1. Parent Window에서 ….
DataWindow dw          //  Child Window에서 Data를 받아 저장할 Parent
Window Object를 선언
//  ex) statictext st or singleeditline sle
…………………….
dw = dw_afd0101d_test  // ex) st = st_test or sle = sle_test
…………………….
openwithparm(w_child, dw) // parameter가 자동적으로 Powerobject로 인식된다.
// 참고로 Parameter는 String, Numeric,
powerobject type이 있다.
// ex) (w_child, st) or (w_child, sle)
…………………….
(일반 Parent Window로부터 받은 Parameter는 일반 Window Object처럼 사용하면 된
다.)
2. Child Window에서 …
DataWindow c_dw                 // statictext st or singleeditline sle
integer    row
…………………….
c_dw = message.powerobjectparm()//Parent Window로부터 Object Type을 받는다.
…………………….
…………………….
row = c_dw.getrow()              //
c_dw.setitem(row, 1, “melong!!”)
// st.text = “melong!!!” or sle.text = “melong!!!”
// 주의) Datawindow일 경우 Column Name이 적용되지
않으므로 반드시 Column Number를 넣어줘야 한다.
…………………….
3. 자알 사용하면 된다..
(만일 1개이상의 Parameter를 넘길 경우…)
예를 들어 1번일경우 statictext object에 값을 넘기고, 2일경우 datawindow object
에 넘길 때…
1. 넘기고자 하는 String 값과 Object를 Structure로 정의해야한다.
즉 structure s_test { string gubun, statictext st, datawindow dw }로 만들어
야 한다.
2. Parent Window에서 Structure Object를 넘겨줘야 한다.
(Parent Window에서)
s_test sr    // Parameter에 대한 Structure를 정의
string gubun
………
gubun = ‘1’ or ‘2’ or ‘3’
sr.gubun = gubun   // 구분을 할 수 있는 값을 지정
sr.st    = st_test // Child Window의 값을 받아올 Static text Object
sr.dw    = dw_test // Child Window의 값을 받아올 Datawindow Object
………
openwithparm(w_child, sr)
………
3. Parameter를 받아 구분에 따라 Child Window값을 Parent Window에 넘긴다.
(Child Window)
s_test     c_sr
integer    row
datawindow c_dw
if c_sr.gubun = ‘1’ then
sr.st.text = “Melong”
elseif c_sr_gubun = ‘2’ then
c_dw = sr.dw
row  = c_dw.getrow()
c_dw.setitem(row, 1, “melong”)
end if
3. 놀면 된다.
■다른 윈도우 어플리케이션이 Running 중인지 체크하는 방법
파워빌더 스크립트 기술시 Running 중에 다른 윈도우어플리케이션이 백그라운드로
Running 중인지를 체크하려면 다음과 같이 한다.
1. Window Object painter의 Declare 메뉴내에 Local External Function 작성.
FUNCTION int GetModuleHandle(string modulename) Library “krnl386.exe”
FUNCTION int GetModuleUsage (int hWnd) Library “krnl386.exe”
2. 파워빌더 스크립트에 다음과 같이 기술.
int val
int  usage
val = GetModuleHandle(“excel.exe”)      //체크하고자 하는 실행화일명을 기술
usage = GetModuleUsage(val)
If usage = 0 then                       //the program is not running
〈process〉
else                                    //the program is running
〈process〉
end if
■윈도우명을 받아서 오픈하기
홍길동이 짠 프로그램에서는 사용자가 입력한 윈도우명을 가지고 해당 윈도우를
오픈하는 경우가 있다. 예를 들어 넘겨준 값이 “w_hello”면 w_hello 윈도우를 오픈
하고 “w_bye”이면 w_bye를 오픈한다.
이럴경우 사용하는 open함수는 다음과 같다
window mywin
string winname
winname = sle_1.text
open(mywin,winname)
■한 프로그램에서 다른 프로그램의 윈도우를 여는 방식과 예제
업무상  한 프로그램(EXE) 에서 다른 프로그램(EXE)의 윈도우를 열어야 할때가 있
습니다. 일단 DDE등을 사용하면 파워빌더의 오브젝트 ( 스트럭쳐나 기타 등등)도 넘
길 수 있지만 그럴 경우 SDI라는 기본 규칙이 깨지게 되지요
어쩔 수 없이(?) 윈도우의 메세지 큐를 이용하는게 좋을 듯 합니다
실행모듈을 부를때 프로그램명과 파라미터를 조합하여 commandparm으로 넘겨주는 방
식이며 아래에 예를 보시고 필요에 따라 수정하여 사용하시면 됩니다
예를 들어 A.EXE의 W_A윈도우의 cb_open버튼을 클릭하면 B.EXE에 있는 W_B 또는
W_C라는 윈도우를 열어준다고 할때(불리워지는 B.EXE의 윈도우에서는 자신이 파라미
터가 필요한지 아닌지 알고 있다고 가정)
부르는 A.EXE의 W_A윈도우의 cb_open버튼의 스크립트 :
RUN(app_path + 실행파일명+불리워지는 프로그램ID+ “;” + 파라미터1 + “;” +
파라미터2 … )
===> run(“c:\test\bis\b SG4;AC;19970417”) //파라미터가 있는 경우
또는
run(“c:\test\bis\b SG5”) //파라미터가 없는 경우
불리워지는 B의 어플리케이션 스크립트 :
f_get_userinfo()
string ProgName,CProgName
ProgName = ProfileString(“c:\bis\bis.ini”,”PgmInfo”,”PgmID”,””)
CHOOSE CASE Progname
CASE ‘SG01’
Open (w_pg01)
CASE ‘SG02’
Open (w_pg02)
CASE ‘SG03’
Open (w_pg03)
CASE ELSE
CProgName = Trim(CommandParm( ))
CHOOSE CASE Left(CProgname,4)
CASE ‘SS04’
Openwithparm(w_b,mid(CProgName,7,len
(CProgname)-6))
CASE ‘SS05’
Open(w_c)
CASE ELSE
Halt
END CHOOSE
END CHOOSE
불리워지는 B의 W_B 의 open 이벤트의 스크립트 :
string ls_cmd, ls_arg[]
integer i, li_argcnt
ls_cmd = message.StringParm
li_argcnt = 1
DO WHILE Len(ls_cmd ) > 0
// 첫번째  구분자 (;) 을 찾는다
i = Pos( ls_cmd, “;”)
if i = 0 then exit
ls_arg[li_argcnt] = Left( ls_cmd, i – 1 )
li_argcnt = li_argcnt + 1
ls_cmd = Replace( ls_cmd, 1, i, “” )
LOOP
ls_arg[li_argcnt] = ls_cmd
기타 등등 …
■리소스(BMP,커서)를 실행파일에 넣으려면…
프로그램의 PB버튼에 예쁜 그림을 넣고 싶을 경우 , 방법이 두가지가 있습니다
하나는 우리가 현재 사용하듯이 BMP를 패스까지 지정하고 PC에 BMP를 넣어주는 방식
입니다. 이럴경우 사용자가 PC의 파일을 지워버리면 화면에 그림이 안뜨겠지요 …
두번째는 실행파일에 넣어놓는 방식입니다
이럴경우 .PBD는 사이즈가 커지겠지만 사용자의 실수로 그림이 안뜨는 일은 없을 것
이고, 실행시 속도도 빠르다고 합니다 (얼마나 빠를지 ?)
자 , 이제 실행파일에 그림을 넣어봅시다
1. 일단 PB버튼의 그림을 지정한 부분에서 디렉토리를 모두 빼줍니다
C:\CIE\BMP\예쁜.BMP ====> 예쁜.BMP
2. .PBR파일을 만듭니다
해당 PBL명과 동일하게 주시고 확장자만 PBR로 주시면 됩니다
아래 SAMPLE.PBR을 다운받아 사용하셔도 되고 메모장에서 그냥 만드셔도 됩니다
예쁜.BMP라고 써 있지요 ?
지우고, 원하는 BMP나 CUR 또는 ICO파일들의 이름을 한줄에 하나씩 엔터를 쳐가
며 넣으시면 됩니다
3. 해당 파일들을 컴파일하려는 PBL과  PBR이 있는 디렉토리에 복사(이동? 아무거
나)합니다.(굳이 이렇게 하지않으려면 위의 PBR파일에 파일명만이 아니고 패스를 모
두 넣어주시면 됩니다. 안그러면 못찾겠다는 메세지가 나올것이라 사료되는바 …)
4. PROJECT를 열어 실행파일을 만듭니다
이때 해당 PBL명 옆에 PBD여부를 체크하시고 그 옆에 리소스어쩌구 하는 부분에
위에서 만든 PBR명을 적어주시면 됩니다
실행버튼을 과감히 누르시고 …
■datawindow를 만들지 않고 dropdowndatawindow기능
datawindow를 만들지 않고 dropdowndatawindow기능을 만들어 봅시다..
예를 들어 부서명을 보여주고 싶은 경우 아래와 같이 작성하면 됩니다.
string var_dept
DECLARE C1 CURSOR FOR
SELECT DEPT FROM PMAS01TT ORDER BY DEPT;
OPEN C1;
DO WHILE true
FETCH C1 into :var_dept
if sqlca.sqlcode = 100 then exit
ddlb_dept.additem(var_dept) //ddlb_dept: DropDownListBox 의 이름
LOOP
CLOSE C1;
■datawindow의 type 바꾸기 ( tabular -> grid )
1. type를 바꾸고자하는 datawindow를 library에서 선택하고 export 시킨다.
2. export된 파일을 편집기로 열어 다음 부분을 변경한다.
datawindow(units=0 timer_interval=0 color=30397132 processing=0 …….
————
datawindow(units=0 timer_interval=0 color=30397132 processing=1 …….
————
3. 변경된 source file을 library에서 해당 pbl에 import한다.
** Datawindow processing attribute **
0 — (Default) Form, group, query, or tabular
1 — Grid
2 — Label
3 — Graph
4 — Crosstab
■Protect Attribute of DataWindow Object
어떤 Row들이 DataWindow에 Retrieve 되었을 경우 각 Row들의 값에 따라서 Edit를
안 하고 싶은 Row가 있을 것입니다. 즉, 다음과 같은 경우가 있다고 가정합니다.
구분               ITEM           항목              값
————————————————–
생산현황    PMB-40H         DAILY 생산        0
PMB-40HS        DAILY 생산        0
PMB 합계  DAILY 생산        0  ← 이 Row만 편집 불가능하게 하고
싶다…
이럴 때 쓰이는 DataWindow Object Attribute가 “Protect”입니다.
어떤 하나의 Column의 Attribute 중 protect를 찾아서 다음과 같이 입력합니다.
→ if(item_code = ‘T’, 1, 0)
※ 여기서는 item_code라는 column은 실제 DataWindow에서는 Delete되었으나
Primary Buffer에는 있다고 가정한 경우입니다.
그렇게 되면, 한 Row에서 item_code 가 ‘T’ 값을 가진 것은 Datawindow Buffer에
서 Edit가 불가능하게 됩니다. 물론 RowFocus도 생기지 않습니다.
하지만, Attribute를 쓰게 되면 DataWindow의 Scrolling Performance가 떨어진
다는 사실은 잊지 마십시오.
■[ENTERA] Datawindow에 Data Display 방법
엔테라를 사용하여 프로그램시, 서버를 Call 하고, 결과를 데이타윈도우에 뿌려
줄 때 현재 SetItem() 혹은 ImportString() 을 쓰고 계실 것입니다.
테스트하여보면,
약 1000건 미만시는 별 차이가 없지만, 데이타가 1000건이상 3000건 정도가 넘어
가면서 ImportString() 을 사용할 경우 퍼포먼스가 급격히 떨어지는 것을 알 수 있
습니다.  이러한 대량의 데이타를 조회할 가능성이 있는 화면의 경우는
ImportString()  대신 다른 방법을 사용하면, 해결할 수 있습니다.
[방법 1.]  SetItem() 으로 셀 단위로 DW 에 Display – 하나의 레코드를 조회,수정
하는 경우나 데이타건수가 많지 않을 때 사용.
[방법 2.]  ImportString() 사용 – Row 단위로 DW에 Display. 데이타건수가 많지
않을 경우 사용(약 1000건 미만)
[방법 3.]  ImportFile() 사용 – Tmp.txt 로 임시파일을 Open 하고, For .. Loop로
읽으면서 FileWrite -> For문이 끝나고, FileClose() 후 ImportFile()
사용 (데이타가 많을 경우 효과적임.)
[방법 4.]  Object Property 중 Current 사용.  -> Column 단위로 DW 에 데이터
Display. (유니텔 swcug – 미들웨어 참조)
예)   String  a1[], a2[], a3[]
rv = dserver(‘AA’, a1[], a2[], a3[])
if  rv <= 0 then
… message 처리
else
dw_sheet.Object.a1.Current = a1
// Object 뒤의 a1 는 DW 의 Column명, = 뒤의 a1 은 String 배열 선언한 변수명.
dw_sheet.Object.a2.Current = a2
dw_sheet.Object.a3.Current = a3
end if
테스트 결과,  대부분의 경우는 ImportString() 을 써도 문제가 되지 않으나, 대량
의 데이타를 조회할 가능성이 있을 경우는 위 방법3, 4 중 한 방법을 사용하시는 것
이 좋을 것입니다.
(ImportFile() 이나 Object.Current 는 거의 비슷한 시간이 걸림.)
■실행중간에 발생한 오류상태처리 (비정상종료를 막으려면..)
1. 기능 설명.
SERVER ERROR 외의 CLIENT ERROR인 경우 DIVIDE BY ZORO 혹은 NULL VALUE 로 인
해 발생하는 에러들은 시스템 다운이나 응용프로그램에러 처리가 되는데 이를 방지
하는 방법으로 에러처리 모듈을 SYSTEMERROR EVENT에 기술하므로써 가능하다.
2. 사용 방법.
1) Application systemerror Event에 아래와 같이 정의.
//————————————————————–//
open( w_system_error ) // 해당 Window Open
//————————————————————–//
2) 수행도중 오류발생시 첨부 화면이 Display 되어진다.
3) W_System_Error Open Event Script. ( Window를 공통으로 사용 )
//————————————————————–//
//  프로그램 진행중 발생한 오류 내역을 화면에 조회한다.         //
//————————————————————–//
DW_Error.InsertRow (1)
DW_Error.SetItem ( 1, “errornum”, string(error.number))
DW_Error.SetItem ( 1, “message” , error.text          )
DW_Error.SetItem ( 1, “where”   , error.windowmenu    )
DW_Error.SetItem ( 1, “object”  , error.object        )
DW_Error.SetItem ( 1, “event”   , error.objectevent   )
DW_Error.SetItem ( 1, “line”    , string(error.line  ))
//————————————————————–//
4) 종료 처리 : W_System_Error 내 ‘cb_exit’ Click Event Script.
//————————————————————–//
//  프로그램 종료 처리                                          //
//————————————————————–//
Halt Close
//————————————————————–//
5) 계속 처리 : W_System_Error 내 ‘cb_continue’ Click Event Script.
//————————————————————–//
//  현재 화면만 종료 후 계속 진행 처리                          //
//————————————————————–//
Close( Parent )
//————————————————————–//
6) 인쇄 처리 : W_System_Error 내 ‘cb_print’ Click Event Script.
//————————————————————–//
//  오류 내역인 인쇄한다.                                       //
//————————————————————–//
DW_Error.Print()
//————————————————————–//
3. 사용 장점
– PB 실행화일 수행도중에 Script 작성 오류로 인한 실행화일 Down 방지.
– 수행도중에 발생한 오류의 상세정보를 제공.
– 심각한 오류가 아닌 경우에는 사용자가 계속 진행 처리할 수 있다.
– 적용하기가 아주 쉽다.( Application systemerror script에 한번만 정의)
■주민번호가 올바른가를 체크하는 로직
주민번호가 올바른가를 체크하는 로직입니다.
1. 주민번호 13자리중 12자리를 처음부터 A라고 하면 12자리 까지만
다음식을 시행한다.
A * 2
B * 3
C * 4
D * 5
E * 6
F * 7
G * 8
H * 9
I * 2
J * 3
K * 4
+  L * 5
= tot
2. tot를 11로 나눈 나머지를 취한다.—-> X
3. 나머지를 11에서 뺀 차를 취한다. —-> 11 – X = Y
4. 차를 구한 값을 다시 10으로나눈 나머지를 취한다. –> Y % 10 = Z
5 1,2,3,4에서 구한 값이 주민번호 끝자리가 된다. —> ‘Z’
6. ‘Z’와 끝자리수를 비교해서 틀리면 주민번호 오류 입니다.
ex)
string jumin
int value[13], i, h_mod, h_minus, h_last, last_jumin
jumin = ‘1215214512120’
last_jumin = dec(Mid(jumin,13,1))
value[1]  = dec(Mid(jumin,1,1))  * 2
value[2]  = dec(Mid(jumin,2,1))  * 3
value[3]  = dec(Mid(jumin,3,1))  * 4
value[4]  = dec(Mid(jumin,4,1))  * 5
value[5]  = dec(Mid(jumin,5,1))  * 6
value[6]  = dec(Mid(jumin,6,1))  * 7
value[7]  = dec(Mid(jumin,7,1))  * 8
value[8]  = dec(Mid(jumin,8,1))  * 9
value[9]  = dec(Mid(jumin,9,1))  * 2
value[10] = dec(Mid(jumin,10,1)) * 3
value[11] = dec(Mid(jumin,11,1)) * 4
value[12] = dec(Mid(jumin,12,1)) * 5
value[13] = 0
FOR i = 1 TO 12
value[13] = value[13] + value[i]
NEXT
h_mod = mod(value[13],11)
h_minus = 11 – h_mod
h_last = mod(h_minus,10)
IF h_last <> last_jumin THEN
MessageBox(“오류”,”주민번호가 아닙니다.”)
RETURN
END IF
MessageBox(“정상”,”주민번호정상”)
//주민번호가 정상이므로 다음 처리
■[Evaluate 함수사용] DropDown Datawindow의 Display값 구하기
데이타윈도우상에서 조회시 DropDown Datawindow를 사용한 경우, 해당 컬럼의
Properties – Edit 에서 DropDown Datawindow를 지정하고, Display Field와 Data
Field를 정의하게 됩니다.
이 때 Data Field의 값은 쉽게 얻을 수 있지만, 만약 Display값을 얻으려고 하면,
간단하게 구해지지는 않지요. 방법은 많겠지만 보통은 GetChild()를 해서 얻을 수
있습니다. 하지만, GetChild()를 사용하지 않아도 한번에 얻을 수 있는 방법이 있습
니다.
예제1)  Emp table을 사용 사원리스트를 조회할 때,
deptno 필드에 부서명을 뿌려주는 DropDown Datawindow가 연결되어 있을
경우,
datawindowchild dwc1
Long rcnt, deptno
string dname
rcnt = dw_1.GetRow()
deptno = dw_1.Object.deptno[rcnt]   // Data값은 쉽게 얻어지지요.
dw_1.GetChild(‘deptno’,dwc1)
long ll_found
ll_found = dwc1.Find(“deptno = “+String(deptno), 1, dwc1.RowCount( ))
if ll_found > 0 then
dname = dwc1.GetItemString(ll_found,2)
// 부서명을 얻기 위하여 Getchild(), Find(), GetItemString() 사용
// 이 Line은 dw_1.Object.deptno.dwc1.Object.dname[ll_found] 로 바꿔도 됩니다.
Messagebox(“dname”,String(dname))
end if
위의 스크립트를 아래와 같이 쓸 수 있습니다.
datawindowchild dwc1
Long rcnt, deptno
string dname
rcnt = dw_1.GetRow()
deptno = dw_1.Object.deptno[rcnt]
dname = dw_1.Describe(“Evaluate(‘LookUpdisplay(deptno)’,”
+String(rcnt)+”) ” )
^^^^^^^^  ^^^^^^^^  ^^^^^^^^^^^^^
Messagebox(“dname”,String(dname))
먼저 Describe()는 데이타윈도우의 속성값을 읽어 오는 함수이며, 반대로 읽어온
속성값을 변경할 경우는 Modify()를 사용할 수 있습니다.
Evaluate()함수는 Describe() 함수와 함께 사용 가능한 함수이며, 데이터윈도우의
조건식을 평가하여 줍니다. (데이타윈도우의 Computed Column내의 Function을 스크
립트상에서 사용가능하게 하여줍니다.) 데이타윈도우 함수중에 Display Value를 얻
을 수 있는 LookUpDisplay() 함수를 사용하면 GetChild()를 하지 않아도 Display 값
을 얻을 수 있게 됩니다.
예제2) 또 다른 Evaluate() 함수의 예제를 보면,
Number Type 컬럼의 Sum을 구하려면,(데이타윈도우상에 Computed Column이
없어도 됨)
String  ls_sum
ls_sum = dw_1.Describe( “Evaluate(‘sum(salary)’,  0)” )
참고로 Describe()의 Return값은 String이며, 성공시 해당 Property값을
Return한다.
( ‘?’ 는 이용할 수 있는 값이 없을 경우, ‘!’는 잘못된 Syntax가 발견될 경우)
Evaluate(‘조건식’, Rownumber)에서 sum과 같은 경우는 Rownumber를 0 을 넣어 주
면 된다. (아무 row값을 넣어 주어도 결과는 제대로 나옴.)
위와 같이 데이타윈도우의 어떠한 Function이라도 스크립트상에서 사용가능합니다.
보통 조회화면에서 입력버튼을 누르면 상세화면을 띄워주고 여기서 입력하는게 보
통인데, 만약 간단한 경우라면 조회한 데이타윈도우에 단지 InsertRow()만 하고 입
력처리할 수 있겠지요. 이 때 조회시에는 Edit할 수 없도록 하고, InsertRow()한 경
우만 Editable 하도록 하고  싶을 경우가 있을 겁니다.
로직으로 TabOrder를 변경할 수도 있지만 번거로울 경우, 간단하게 Protect
Property로 해결할 수 있습니다. 데이타윈도우 Painter에서 해당 컬럼의 Properties
를 엽니다. 맨 끝의 Expressions에 보면 컬럼의 속성값중 Protect란에
If( IsRowNew(), 0, 1)
이라고만 등록하여 놓으면, 조회시는 Focus가 안가고(Edit할 수 없고),
입력시(InsertRow())만 Edit 가능해집니다.
■[DW Syntax] 사용하기
파워빌더 유틸리티중에 Install Builder외에는 별로 사용할 기회도 없고, 또 잘
모르는 경우가 많습니다.
유틸리티중에 DW Syntax 5.0 이 있습니다.
PB 5.0 으로 오면서 강력해진 기능중에 Dot Notation(dw_1.Object….) 과 같은
좋은 기능이 있지만, 막상 속성값을 쓰려하면 어떤 것들이 있고, 또 어떻게 써야 할
지 몰라서 못쓰는 경우가 많고, 또 Help를 봐도 잘 찾아 지지 않지요.
데이타윈도우의 각종 Object(Datawindow, Bitmap, Column, Text, Graph, Computed
Field,,,)들의 속성값을 참조( Describe() )하거나 변경( Modify() ),
생성( Create() ), Destroy 등의 경우에 따라 사용예를 보여 줍니다.
파워빌더 툴바에서 오른쪽 클릭하고, Custom 선택하여 맘에 드는 아이콘 찍고, 여
기에 Brouse로  파워빌더 디렉토리에 가보면 DWSyntax 라는 실행파일이 있고, 이것
을 선택하면 툴바에서 필요할 때 참조할 수 있겠지요.
■해당년월의 마지막날을 구하는 스크립트
해당년월의 마지막날을 구하는 스크립트입니다.
//  user object를 사용한 경우
int  li_year, li_month
// 1. 구하고자 하는 마지말날의 해당 년월을 구한다.
li_year = integer(left(uo_1.em_date.text,4))
li_month = integer(right(uo_1.em_date.text,2))
// 2. 해당월의 다음달 첫째일을 구한다.
li_year += int(li_month / 12)
li_month = mod(li_month, 12) + 1
// 3. 구한 날에서 RelativeDate 함수를 사용하여 하루를 빼면
그날이 구하고자 하는 마지막날이 된다.
Date ll_date
ll_date = RelativeDate(date(li_year, li_month, 1), -1)
sle_1.text = right(string(ll_date, ‘yyyymmdd’),2)
■데이타윈도우 내용을 엑셀로 내려받기
데이타윈도우의 데이타를 엑셀로 내려받을때 컬럼명이 영문으로 나오는 것을 볼
수 있습니다.
화면에서의 컬럼명처럼 엑셀파일에서도 한글컬럼명이 보여지기를 원할 때 다음과
같이 작성하시면 원하는 결과를 얻을 수 있습니다.
a_code : dw 의 컬럼명
dbname : dw 컬럼 property
a코드 : 바꾸고자 하는 한글컬럼명
dw_sheet.modify(“a_code.dbname = ‘거래선코드'”)  // 엑셀 title이 거래선코드
dw_sheet.modify(“a_name.dbname = ‘거래선명'”)
dw_sheet.modify(“pers_name.dbname = ‘대표자명'”)
dw_sheet.modify(“phon_numb.dbname = ‘전화번호'”)
dw_sheet.SaveAs(“c:\mis\test.xls”,excel!,true)
■일정시간이 지나면 자동으로 시스템을 종료하게 만드는 스크립트
일정시간이 지나면(예를들어 30분) “30분동안 시스템을 사용하지 않아 종료합니
다”라는 메세지와 함께 시스템을 강제종료시키는 스크립트입니다.
보안적용에 사용하시면 좋을것같아 올립니다.
1. 먼저 main frame Window의 Open event에
Idle(1800)
이라고 coding합니다.  여기서 1800은 60(초) * 30(분)을 의미합니다.
2. 해당 Application의 idle event을 open하여
Messagebox(“확인”,”30분동안 음악시스템을 사용하지 않았습니다. ~r~n” +&
“음악시스템을 종료합니다.”)
Halt
라고 coding해주면 30분 후 메세지와 함께 자동으로 시스템을 종료하여 주게됩니
다. (테스트해보니깐 조회나 Insert등의 내부작업을 하고있으면 강제종료하지 않더
군요…)
출처 : http://junlife.tistory.com/57

 

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

*