천객만래 [千客萬來] (It has an interminable succession of visitors)

<파워빌더 ODBC 인터페이스> 

  
 다음은 파워빌더7.0과 인포메이커 애플리케이션이, ODBC를 사용하여 데이터베이스에 
 접속하고자 할 때 필요한 파일 목록입니다. 

  
 파일명 설명

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

 PBODB80.DLL PowerBuilder ODBC interface

 PBODB80.INI PowerBuilder ODBC initialization file

 

 설치된 경로 > C:Program FilesSybaseSharedPowerBuilder

 설치될 경로 > 설치할 프로그램 폴더, System Path 또는 Path가 지정된 특정 폴더

  INI파일과 DLL파일은 반드시 같은 디렉토리에 위치해야 합니다. 

  
  

 <마이크로소프트 ODBC 파일> 

  
 개발된 애플리케이션이 ODBC를 이용하여, 데이터베이스에 접속할 경우,

 다음의 마이크로소프트 ODBC 3.5파일들이 필요합니다.

 보통 윈도우 설치시 함께 설치되어 있습니다.

 다시 설치할 필요가 있으면 설치 CD 안에 Support 폴더에 있는 MDAC_TYP.EXE을

 실행하여 업데이트할 수 있습니다. 

  
 파일명 설명

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

 DS16GT.DLL Microsoft ODBC driver manager, DLLs, and Help files

 DS32GT.DLL

 ODBC32.DLL

 ODBC32GT.DLL

 ODBCAD32.EXE

 ODBCCP32.CPL

 ODBCCP32.DLL

 ODBCCR32.DLL

 ODBCINST.CNT

 ODBCINST.HLP

 ODBCINT.DLL

 ODBCTRAC.DLL

 

 설치된 경로 > Windows system directory

 설치될 경로 > Windows system directory 

    

 <어댑티브 서버 애니웨어 파일> 

  
 개발한 PowerBuilder 애플리케이션이 어댑티브 서버 에니웨어(ASA)데이터베이스를 사용한다면,

 배포시 ASA의 ODBC 데이터베이스 드라이버와 ASA DBMS를 함께 배포하셔야 합니다.

 개발된 애플리케이션이 독립형(stand-alone) 데이터베이스를 사용할 경우에는

 ASA의 데스크탑 런타임 모듈을 최종 사용자의 PC에 무상으로 배포하실 수 있습니다.

 이 런타임 모듈은 사용자가 데이터베이스내에 있는 데이터를 조회하거나 변경하는 것은 허용하나,

 데이터베이스의 스키마(schema)를 변경하는 것은 허용되지 않습니다.

 또한 트랜젝션 로그(Transaction logs)나 저장 프로시져(Stored procedures),

 트리거(Trigger)를 지원하지 않습니다.

 ASA(Adaptive Server Anywhere)드라이버와 런타임 엔진 그리고 기타 지원 파일들을 모두 인스톨

 하실 때는 파워빌더 인스톨 CD에 있는 "Support" 디렉토리에 있는 파일들을 설치 하십시오.

 

 파일명 설명

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

 DBODBC7.DLL ASA ODBC driver

 DBBACKUP.EXE ASA backup utility

 DBCON7.DLL Connection dialog box, required if you do not provide your own dialog box and

  your end users are to create their own data sources, if they need to enter

  user IDs and passwords when connecting to the database, or if they need to

  display the Connection dialog box for any other purpose

 DBISQLC.EXE Interactive SQL utility

 DBLGEN7.DLL Language-specific string library (EN indicates the English version)

 DBLIB7.DLL Interface library

 DBODTR7.DLL ODBC translator, required if your application relies on OEM to ANSI character set
 conversion

 DBTOOL7.DLL ASA database tools

 DBUNLOAD.EXE ASA unload utility

 DBVALID.EXE ASA validation utility

 RTENG7.EXE 제한적 용도의 런타임 엔진

 DBCTRS7.DLL Performance utility

 DBSERV7.DLL Server utility

 DBWTSP7.DLL Tools support

 

 설치된 경로 > C:Program FilesSybaseSQL Anywhere 7win32

 설치될 경로 > 설치할 프로그램 폴더, System Path 또는 Path가 지정된 특정 폴더

  기타지원 파일들은 반드시 DBODBC7.DLL이 있는 디렉토리에 설치되어야 합니다.

 ODBC 정보설정> ODBC에 대한 정보를 레지스트리에 등록해야 합니다.

 

 - ODBC.INI

 프로그램을 특정 데이터소스에 ODBC를 통해 연결하려면 레지스트리 정보 중 'ODBC.INI' 항목에

 데이터소스에 대한 정의가 필요합니다.

 'ODBC.INI'항목은 'HKEY_CURRENT_USER' 또는 'HKEY_LOCAL_MACHINE'에 있는데 앞에 것은

 사용자 DSN에 등록되는 내용이며 뒤에 것은 시스템 DSN에 등록되는 것입니다.

 DSN에 대한 설정내용은 제어판의 'ODBC 데이터 원본 관리자'에서 확인할 수 있습니다.

 이 내용은 프로그램이 데이베이스를 구동할 때 제공할 정보들입니다.

 

 [HKEY_CURRENT_USERSOFTWAREODBCODBC.INIMyApp DB]

 "Driver"="C:Program FilesSybaseSQL Anywhere 7win32dbodbc7.dll"

 "Start"="c:program filessybaseSQL Anywhere 7win32rteng7.exe -c8m"

 "UID"="dba"

 "PWD"="sql"

 "Description"="Database for my application"

 "DatabaseFile"="C:Program Filesmyappsmyapp.db"

 "AutoStop"="Yes"

 

 [HKEY_CURRENT_USERSOFTWAREODBCODBC.INIODBC Data Sources]

 "MyApp DB"="Adaptive Server Anywhere 7.0"

 

 - ODBCINST.INI

 프로그램이 실행될 PC에 설치된 ODBC 드라이버에 대한 정보입니다.

 드라이버 설치정보는 제어판의 'ODBC 데이터 원본 관리자'에서 확인할 수 있습니다.

 

 [HKEY_LOCAL_MACHINESOFTWAREODBCODBCINST.INIODBC Drivers]

 "Adaptive Server Anywhere 7.0"="Installed"

 "PB Merant OEM 3.60 32-BIT Sybase"="Installed"

 

 [HKEY_LOCAL_MACHINESOFTWAREODBCODBCINST.INIAdaptive Server Anywhere 7.0]

 "Driver"="c:program filessybaseSQL Anywhere 7win32dbodbc7.dll"

 "Setup"="c:program filessybaseSQL Anywhere 7win32dbodbc7.dll"
 
 질문)

 "kernel32.dll" 에 포함되어 있는 CreatFile,WriteFile,CloseHandle 함수를 쓸려고 하는데

 파워빌더 Global External Function 에서 어떻게 변수들을 정의하고 값을 정의 하는지 알고 싶어서요.

 MSDN 사이트 들어가봐도 약간 찾기가 힘드네요..그럼 수거하세요.
Posted by SB패밀리


파워빌더 리스트뷰(ListView) 속도 문제

파워빌더의 Compile->Run을 통해 수행할 때와
파워빌더에서 Deploy 후 exe 파일에서 수행할 때의 속도문제


ListView에서 *.bmp 파일을 로딩할 때와
그 이외의 이미지 확장자를 이용할 때의 이미지 추가할 때의 속도가 다르다.

파워빌더의 Compile->Run을 통해 수행할 때에는 눈에 띄게 구별되지 않아
문제가 되지 않는다.

하지만, 파워빌더에서 Deploy 후 exe 파일에서 ListView 컨트롤에서
이미지를 추가할 때 속도가 눈에 띄게 느리다. 대략 1~3초 사이가 걸린다.
컴퓨터 사양에 따라서 다를 수 있지만 누가봐도 차이가 난다는 사실이다.

ListView를 이용하여 개발하는 개발자라면 이 사항은 꼭 참고하기 바란다.

Posted by SB패밀리

파워빌더 성능 관리
 
근래에 파워빌더로 개발된 곳에서 성능 측정을 요구하는 곳이 많아 지원을 가보면 
일반적으로 고려하여야 할 사항을 무시하고 개발된 곳이 대부분이라 성능이 문제가 되고 있었다.

파워빌더의 문제라기보다는 파워빌더에 맞는 고려사항을 인지하지 못한 탓이다. 
이런 이유로 고객의 요구에 의해 본사에서 시행하는 성능관리 교육교재를 요약하여 싣는다.

(Managing Performance in 
     PowerBuilder)
 
목차 
 
1 장: 
     개요

2 장: 
     해당 실행 모듈 호출

3 장: 
     스크립트 실행 

4 장: 
     데이터 조회

5 장: 
     그 외 사항 
 
1 장: 
     개요
 
성능 이란 
       ?

성능과 관련된 문제점과 토론 사항

성능 향상 정책 수립

사용자 인식 관리

  
 
1.1 
       성능이란 ? 
 
사용자 관점의 성능
성능이라는 것은 실행 시 얼마나 빨리 시스템이 응답하느냐는 것이다. 

개발자 관점의 성능
성능은 다음과 같은 사항을 고려 

서버의 부하
네트웍의 거리
사용자 수
클라이언트와 서버의 구성
데이터베이스 설계와 정규화
애플리케이션의 설계와 작성
사용자의 인지도 
1.2 
       일반적인 성능 불만 사항 
 
윈도우를 열 때 
데이터 조회 시 
애플리케이션 실행 시
필드간 이동 시 
윈도우 간 이동 시
계속하여 실행 시
 
 
1.3 
       문제 발생 요인 
 
해당 실행 모듈 호출
스크립트 실행
데이터 조회
하드웨어와 소프트웨어 구성 
1.4 
       성능 향상 정책 수립 
 
문제점 분리
문제점 범위 지정
이벤트
함수
과정
기능
모든 것이 느리다는 것은 용인되지 않음 
 
 
1.5 
       애플리케이션 환경 점검 
 
애플리케이션의 문제인지 구성 문제인지 ? 
보다 더 성능이 뛰어난 기계에서 실행
관련 모듈을 클라이언트에 설치 
 
 
 
 
1.6 
       설계 재점검 
 
잘못된 설계는 성능에 영향을 미침
기존 프로그램 수정보다는 설계 변경이 효과적 
1.7 
       주의 사항 
 
존재하지도 않는 성능 저하 문제점을 해결하려고 시간 낭비 하지 말 것
뛰어나게 효과가 나지 않을 때는 변경 자제
관리하기 어려운 방식으로 문제 해결하지 말 것 
한번에 많은 변경을 하지 말 것 
 
 
1.8 
       벤치마크 
 
성능을 정량적으로 측정하는 방법
다음 사항을 측정하기 위한 벤치마크 설정
문제점이 실제적으로 성능 저하 요인인가 ?
변경이 성능을 향상 시키는가 ?
주관적인 측정치에 의존하지 말 것 
1.9 
       시간 측정 
 
LONG ll_start, ll_elapsed

// 시작 시간 지정

ll_start = CPU( )

// 측정할 과정 기술

...

// 경과 시간 계산

ll_elapsed = CPU( ) - 
ll_start

파워빌더 
         6.0에서는 프로파일러 이용하여 성능 측정

1.10 
       부하를 이동하거나 분산 
 
긴 작업을 작은 단위로 나눔:
모든 데이터를 조회 후 윈도우를 보여 주는 것 보다는 
윈도우를 먼저 보여 주고 데이터를 가져와서 보여 주는 게 효과적
동일하게 시간이 걸려도 사용자는 덜 지루함 
1.11 
       사용자에게 볼 것을 제공 
 
마우스 포인터 모양 변경
도움말(MicroHelp) 제공
진행과정을 측정기로 보여 줌
취소를 할 수 있게 
 
 
2 장: 
     해당 실행 모듈 호출

모듈 호출

클래스 정의 올리기

관련된 컨트롤과 메뉴 만들기

스크립트 실행

데이터 조회

  
 
2.1 
       모듈 호출 시 영향을 주는 요소 
 
클래스 정의 호출
관련된 컨트롤과 메뉴 생성
스크립트 실행
데이터 조회 
2.2 
       윈도우가 나타나는 과정 
 
클래스 풀에서 해당 모듈을 찾는다.
클래스가 풀에 없으면 라이브러리에서 찾는다. (지정된 라이브러리 순서대로)
윈도우를 생성.
각종 컨트롤을 생성.
관련된 메뉴를 만든다.
각 컨트롤의 Constructor 
       이벤트
윈도우 Open, 
       Activate, Show, Resize 이벤트
스크립트에 있는 데이터 조회 수행
데이터윈도우에 지정된 기능 수행(Sort, Filter..) 
2.3 
       클래스 정의 호출 
 
라이브러리 정비
성능 면이 아닌 관리 측면에서
한번 호출한 것은 등록되어 다시 찾지 않음
각 PBL당 PBD, EXE 모듈은 작게
관련된 모듈끼리 동일 라이브러리에
클라이언트에 파일을 설치 
성능은 향상이 되더라도
분산과 사용자 버전관리가 문제 
2.4 
       관련된 컨트롤과 메뉴 생성 
 
한 윈도우에 컨트롤의 개수를 제한 
       ( 20개)
되도록 이면 데이터윈도우 사용
윈도우 자원 적게 사용
데이터 입력 오류 검증
코드 테이블
드롭다운데이터윈도우
커스텀유저오브젝트 사용 제한
각 컨트롤 수 + 
         1
오브젝트의 크기는 성능에 영향 없음
실행 시 정의되는 인스턴스 변수는 상수로 대치 
2.5 
       재원 
 
사용되는 bmp, 
       ico 등의 PBR은 EXE에 포함 
검색 과정:
EXE - 
         PBD나 DLL - 현재 디렉토리 - 
         \Windows와 \Windows\System 디렉토리 -DOS path
원래 크기 사용
bmp, ico 만 가진 PBD, DLL ? 
2.6 
       필요 시 오브젝트 생성 
 
비즈니스 로직만 가진 유저오브젝트를 만들어 필요 시만 생성하여 사용
데이터스토어가 숨긴 데이터윈도우 컨트롤보다 좋음
OpenUserObject()을 사용하여 필요 시에만 인쇄하는 목적의 데이터스토어 생성
탭 컨트롤에는 CreateOnDemand 
       기능 사용 
2.7 
       상속 
 
상속 다단계는 문제가 되지 않음(메뉴 제외)
상속은 관리나 실행 시 이득
엔시스터의 비대와 상속 다단계는 고려 
2.8 
       클래스 풀 
 
클래스 정의는 클래스 풀에 저장
마지막 인스턴스가 종료되면 지워짐
자주 사용되는 엔시스터 정의는 클래스 풀에 상주시키는 것이 유리 
2.9 
       메뉴 
 
문제점을 분리하기 위해 메뉴를 삭제
각 메뉴 아이템은 오브젝트 하나로 제한고려
탭 컨트롤, 또 다른 윈도우
메뉴 상속은 성능에 악영향 ( 2 ~ 3 단계 ) 
2.10 
       스크립트 수행 
 
문제점을 분리하기 위해 스크립트를 코멘트화
긴 시간 수행 스크립트는 Post
오브젝트 생성시 영향을 주는 이벤트
Open 이벤트
Activate 
         이벤트
각 컨트롤의 Constructor 
         이벤트
GetFocus 
         이벤트
Show와 Resize 
         이벤트 
OpenWithParm()이나 OpenSheetWithParm()으로 윈도우 간에 데이터 교환 시 스트럭춰를 사용하기 보다는 유저오브젝트를 사용
AutoInstantiate 속성은 사용 금지 
2.11 
       메뉴 변경 
 
Hide보다는 
       Disable이 유리
ChangeMenu( ) 
       사용 금지 
2.12 
       데이터 조회 
 
먼저 윈도우를 보여 주고 데이터 조회
조건상 반드시 윈도우와 데이터를 동시에 보여 줄 경우에는 Retrieve As Needed 속성을 지정하고
Open 이벤트에서 Post 
       된 이벤트에 다음과 같은 스크립트를 지정
dw_1.Modify ( 
       ‘DataWindow.Retrieve.asneeded=no’ )
한 화면의 데이터만 필요 하다면
Retrieve As Needed 
       속성을 지정하고
Open 이벤트에서 Post 
       된 이벤트에 다음과 같은 스크립트를 지정
dw_1.DBCancel( 
       )
그 후에 적당하게 Retrieve() 
       함수를 수행 
2.13 Open 
       이벤트는 데이터 조회 삼가 
 
일반적으로 많이 사용되어지는 DDDW는 미리 조회하여 
       ShareData() 함수를 사용하여 공유
사용자가 요청 시에만 데이터 조회를 수행하는 것도 고려 
3 장: 
     스크립트 수행
 
머쉰 코드로 컴파일 

화면 재생성

데이터윈도우 관련 스크립트

루프와 배열

변수

함수와 이벤트

고려할 그 외 사항

  
 
3.1 
       머쉰 코드로 컴파일 
 
장점
변수 참조
수학적 계산이나 할당
로직을 전개하기위한 IF, CHOOSE, FOR, 
         DO 등의 문장 
함수 호출
스크립트에 관련된 사항만 향상
제한 사항
해당 모듈 호출
데이터윈도우 성능
데이터 조회
파워스크립트 함수
예: 
       Retrieve( ) 
함수는 빠르게 호출 되나
서버나 네트웍에는 영향을 미치지 못함 
3.2 
       머쉰코드와 데이터윈도우 기능 
 
파워빌더 5.0과 6.0에서는 다른 문제 해결 방법
데이터윈도우의 “.” 표기
파워빌더 4.0
For 
         ...
li_empid[ll_row] = 
           dw_1.getitemnumber

(ll_row,’emp_id’) 

파워빌더 
       5.0과 6.0
li_empid = 
         dw_1.object.emp_id.current 
3.3 
       화면 재생성 
 
화면 재생성: SetRedraw( ) 
       사용
w_main.SetRedraw(FALSE)
sle_name.Text = 
           ""

sle_address.Show( 
           )

p_photo.PictureName = "photo.bmp"

...

w_main.Title = 
           "Employee Data"

w_main.SetRedraw(TRUE) 
 
3.4 
       단수 속성 참조 
 
Describe( ) 함수
rc = 
         dw_1.describe(“dept_id.x”)
직접 속성 지정
rc = 
         dw_1.object.dept_id.x 
3.5 
       복수 속성 참조(빠른 순서) 
 
복합 
       Describe( ) 함수
modstring = 
         “dept_id.X dept_id.Y” + &
" dept_id.height 
           dept_id.width"

rc=dw_1.Describe( 
           modstring ) 

각각의 
       Describe( ) 함수
각각의 직접 속성 지정
li_x = 
         dw_1.Object.dept_id.X 
3.6 
       단수 속성 지정 
 
Modify( ) 함수
dw_1.Modify( 
         “customer_name.Font.Italic=1”)
직접 속성 지정
dw_1.Object.customer_name.Font.Italic=1 
3.7 
       복수 속성 지정(빠른 순서) 
 
복합 Modify( 
       ) 함수
ls_modstring= 
         "customer_name.Font.Italic=1~t 
customer_city.Color=255"
dw_1.Modify( 
         ls_modstring )
복합 Modify( 
       ) 함수는 SetRedraw( ) 
       사용
직접 속성 지정 시에도 SetRedraw( ) 사용 
3.8 
       데이터 조회 
 
GetItemx( )
ll_id = 
         dw_1.GetItemNumber(1, "emp_id")
직접 참조
ll_id=dw_1.Object.emp_id [1]
GetItemx( ) 가 빠르다.
직접 참조는 블럭 단위 조회 시 유리
예: 
       컬럼 복사
기존 4.0 
         방식: 

string ls_array[ 
         ]
long ll_numrows, 
           i

ll_numrows = 
           dw_1.rowcount ( )

FOR i = ll_numrows 
           to 1 step -1

ls_array [i] = 
           dw_1.GetItemString(i, "emp_name" )

NEXT

5.0과 6.0 방식: 

string ls_array[ 
         ]
ls_array = 
           dw_1.Object.emp_name.Current 
 
3.9 
       데이터 변경 
 
SetItem( )
dw_1.SetItem( 1, 
         "emp_id", ll_id )
직접 변경
dw_1.Object.emp_id 
         [1] = ll_id
SetItem( ) 이 빠르다.
직접 변경은 블럭 단위가 유리. 
3.10 
       데이터윈도우 간의 데이터 공유 
 
반복적으로 조회 불필요
메모리 상에서 데이터 복사는 되도록 회피 
3.11 
       데이터윈도우 간의 데이터 복사 
 
RowsCopy( )
직접 지정
dw_1.Object.Data = 
         dw_2.Object.Data
ImportClipboard( )
ImportString( )
GetItemx( ) / SetItem( ) 
       loop 
3.12 
       선택된 로우만 복사 
 
dw_2.Object.Data = 
       dw_1.Object.Data.Selected
GetSelectedRow( ) 와 RowsCopy( )보다 유리 
3.13 
       데이터윈도우 이벤트 
 
RetrieveRow 이벤트
이벤트 아규먼트 사용
ItemChanged 
         이벤트에서 GetRow() 대신에 Row사용
ItemChanged, EditChanged, 
       ItemFocusChanged, pbm_dwnkey, RowFocusChanged 이벤트에는 되도록 가볍게 작성 
3.14 
       컬럼 이름과 컬럼 번호 
 
컬럼 이름이 관리상 유리
GetItemx( )과 SetItem( )일 경우에는 번호가 조금 빠르고
직접 지정 일 경우에는 번호가 현격하게 빠르다. 
3.15 
       테이블 간의 데이터 이동 
 
데이터파이프라인 사용하는 방법과 데이터윈도우를 중간에 개입하는 방법
데이터파이프라인이 현격하게 빠르다. 
3.16 
       루프와 배열 
 
배열 초기화
intoriginalarray[ 
         ]
intdummyarray[ 
           ]

originalarray = 
           dummyarray 

함수에서 배열을 교환 할 경우에는 Pass by 
       reference나 Read Only 사용
루프내에서 동일한 값을 리턴하는 함수 사용금지
되도록 루프 내에는 작게 작성
이 방식 보다는:
FOR li_index = 1 
         TO UpperBound(li_array)
... 

이방식이 유리:
int 
         li_array_len
li_array_len = 
           UpperBound(li_array)

FOR li_index = 1 
           TO li_array_len

...
 
3.17 
       동적 배열 
 
동적 배열을 사용 할 경우에는 반대로
FOR li_index = 1 
         to li_max
li_array[li_index] 
           = li_index * 10

NEXT 

FOR li_index = 
         li_max to 1 STEP -1
li_array[li_index] 
           = li_index * 10

NEXT 

정적 배열이 동적 배열보다 유리 
3.18 
       변수 
 
참조 시간
Global[t] = 
         Shared[t] 나 Instance[t] * 2
Global[t] = 
         Local[t] * 3
변수 지정 영역
동일 이벤트나 함수 내에서 변수 선언 장소는 문제되지 않음
상수는 개발 시 변수는 실행 시 지정
Any 데이터 타입은 사용 자제 
3.19 
       함수 
 
파워빌더에서 이미 제공하는 함수는 만들지 말 것
해당 오브젝트에 포함되는 함수가 광역 함수보다 유리
지정과 미지정은 동일
wf_save()
Parent.wf_save() 
3.20 
       이벤트와 함수 
 
먼저 성능과는 무관하게 이벤트로 할지 함수로 할지를 결정
4.0과 달리 
       5.0과 6.0에서는 이벤트와 함수가 유사
차이점으로는
이벤트는 오브젝트과만 연관됨
정의되지 않은 함수는 에러 발생
함수는 영역 지정 가능
함수는 찾는 과정이 복잡(외부->광역->오브젝트->앤시스터)
성능 비교(속도가 빠른 순위)
정적 이벤트와 정적 함수
TriggerEvent( ) 
         함수
동적 함수
동적 이벤트 
3.21 
       고려할 그 외 사항 
 
단축 지정 문장이 유리
++, 
         ---
코멘트 삭제
RetrieveRow 
         이벤트에는 되도록 삭제
이벤트
자주 발생하는 이벤트에는 되도록 짧게 작성(MouseMove, 
         Other...)
CHOOSE 
       CASE가 IF / ELSEIF보다 관리면에서 유리
오브젝트 참조 변수
ParentWindow( ) 
         함수를 계속 사용하기 보다는 변수 선언이 유리 
4 장: 
     데이터 조회
 
일반 사항

데이터베이스 설계

SQL 
       튜닝

결과치 감소

데이터 케싱

클라이언트와 서버에 분할

데이터윈도우 오브젝트 실행

  
 
4.1 
       일반 사항 
 
언제 데이터가 필요 한가 
?
반드시 모든 데이터가 필요 한가 
?
결과치를 줄일 수 있는가 ?
설계는 맞는가 ?
데이터베이스 관리자가 관여 하였는가 
       ! 
4.2 
       데이터베이스 연결 최소화 
 
Connect;와 
       DisConnect;를 적절히
SetTrans( 
       )보다는 SetTransObject( ) 사용 
4.3 
       역정규화 
 
정규화 된 데이터베이스는 복잡한 조인을 요구
조인을 줄이기 위하여 역정규화
요약 정보 테이블 생성이 필요 
4.4 
       트랜잭션 관리 
 
COMMIT과 
       ROLLBACK을 적절히 사용하여 서버에서 잡고 있는 자원을 풀어 줌
Retrieve()만 한 경우도 서버의 자원을 잡고 있을 수 있음 
4.5 SQL 
       문장 케싱 
 
반복적인 SQL 문장 
DBParm 속성: Oracle, 
       ODBC
SQLCache=<케쉬하고자 하는 문장 개수>
SQLCache=0 
       케쉬 취소
SQLReturnData를 사용하여 크기 결정
연결 종료 시 케쉬 정보가 들어옴 
4.6 
       바인드 기능 
 
동일한 SQL 문장이고 데이터 값 만 변경이 일어날 경우 한번만 컴파일
DBParm 속성
가 능: DisableBind=1
불가능: 
DisableBind=0
SQLPreview 
       이벤트에서 확인
바인드 적용:
UPDATE department 
         SET dept_name = ?, dept_head_id = ? WHERE dept_id = 
       ?
바인드 비적용:
UPDATE department 
         SET dept_name = ‘Sales’,dept_head_id = 35 
WHERE dept_id = 
         300 
 
 
4.7 
       문제점 분리 
 
SQL 질의를 두 군데에서 
데이터베이스 관리자 페인터
데이터윈도우 페인터
성능이 만족되는가 ?
예: 데이터윈도우 컨트롤의 스크립트를 점검
아니오: SQL 문장 자체를 점검 
4.8 SQL 
       문장은 단순하게 
 
WHERE 절의 
       LIKE를 사용 절제
복잡한 질의를 단순하게 분리
조인은 되도록 삼가 
4.9 
       조인 대신에 DDDW 
       사용 
 
DDDW를 과다하게 사용하면 성능 저하
항상 DDDW가 조인보다 빠른 것이 아님 
4.10 
       데이터윈도우의 변경 속성 조정 
 
WHERE 절이 성능에 지대한 영향
성능이 아닌 동시성과 지속성에 중점 
4.11 
       그 외 SQL 
       관련 사항 
 
스크립트 내에 SQL을 삽입하기 보다는 데이터윈도우나 데이터스토어를 사용
RPC나 스토어드프로시줘를 사용
Explain SQL 
       기능을 이용하여 SQL 질의를 최적화 
 
 
4.12 
       결과치 감소 
 
필요한 데이터만 조회
SELECT * FROM 
         TABLE 금지
조회 취소
결과치 최소화
보고서가 아닌 온라인 조회일 경우 100 건 이상은 현실성 부족
필요한 컬럼을 미리 조회
데이터기 변경이 없다면 데이터윈도우 오브젝트를 데이터와 함께 저장 
4.13 
       하드디스크에 데이터 저장 
 
Rows->Retireve->Rows to Disk 
4.14 
       클라이언트와 서버에 분할 
 
정열
필터링
통계나 계산 
그룹핑
데이터 확인 
4.15 
       데이터윈도우 수행 
 
데이터윈도우는 별도의 엔진을 사용하므로 머쉰코드로 만들더라도 별 효과 없음
데이터윈도우에 지정된 모든 기능은 별도의 데이터윈도우 엔진이 모두 담당
계산 필드, 데이터 확인, 포맷, 정열, 필터 
4.16 
       계산 필드 
 
각 로우 별로 조회 후 계산되므로 성능 저하 요인이 되므로 되도록 계산 컬럼을 사용하는 게 유리 
4.17 
       디스플레이시 영향을 주는 것 
 
슬라이드 컬럼
AutoHeight 
       컬럼
bmp 참조 시
EXE에 포함시키거나
폰트를 활용(Wingding...)
그래프로 데이터표현 시 레이블을 회전시키지는 말 것 
4.18 
       내부 기능 
 
네스티드 데이터윈도우 사용 시에는 케쉬나 바인드 기능을 사용
5.0과 
       6.0에서는 데이터윈도우에 새로운 데이터 형식이 있으므로 해당 형식에 맞게 지정
int
long
real 
4.19 
       조회 전 데이터윈도우와 테이블 비교 
 
파워빌더는 조회 전 데이터윈도우에 정의된 정보와 테이블의 내용이 일치하는지 미리 조사 한 후 조회
DBParm 속성 지정
결과치 비교 조사 취소: 

SQLCA.DBParm = 
         'StaticBind=1'
 

결과치 비교 조사 : 
         

SQLCA.DBParm = 
         'StaticBind=0' 
5 장: 
     그 외 사항
 
애플리케이션 성능 저하

애플리케이션 여는 시간

포커스 이동

DDDW가 늦게 열림

윈도우 활성

라이브러리 관리

시스템 구성

  
 
5.1 
       애플리케이션 성능 저하 
 
열었으면 닫아야 함
생성했으면 제거도 하여야 함
OpenUserObject( 
       )을 사용하였으면 CloseUserObject( )도 기술
OpenTab( ) 
       을 사용하였으면 CloseTab( ) 도 기술
연결하였으면 연결 종료도 하여야 함 
5.2 
       변수 선언 없이 생성 
 
변수 선언 없이 유저오브젝트를 생성하지 말 것
n_trans = CREATE 
         n_trans
문장 상으로 문제는 없으나 계속적으로 필요 없는 것이 생성됨 
5.3 
       애플리케이션 열기 
 
애플리케이션 시작 시에 다음에 필요한 작업을 하는 것도 고려 해 볼만 함
데이터베이스 연결 및 초기화
코드 테이블 조회
보안
만약에 애플리케이션 여는 시간이 문제라면 메인 윈도우에서 처리 
 
 
5.4 
       데이터윈도우 컬럼 간 이동 
 
ItemChanged 
       이벤트
ItemFocusChanged 
       이벤트
RowFocusChanged 
       이벤트
데이터 검증 룰
계산 필드
조건부 수행 
5.5 
       컨트롤 간 이동 
 
LoseFocus 
       이벤트
GetFocus 
       이벤트 
5.6 
       포커스 이동 시 문제점 해결 
 
중요하지 않은 과정은 Post
스크립트 수정
데이터 조회 시점 변경
데이터윈도우 오브젝트 점검
앤시스터 스크립트 확인 
5.7 
       DDDW가 늦게 열림 
 
각 DDDW가 각각 조회하는 것보다는 공유
pbm_dwndropdown 
       이벤트 점검 
5.8 
       윈도우 활성 
 
윈도우 활성이 늦으면 Activate, DeActivate 이벤트를 점검
시간이 걸리는 데이터조회는 
         Post
Activate 
         이벤트에 메뉴 관련 로직은 삼가
쉬트를 관리하기 위한 로직이 Activate 이벤트에 있다면 GetFirstSheet( ), 
         GetNextSheet( ), GetActivateSheet() 함수로 대치하여 전개 
5.9 
       라이브러리 관리 
 
대규모 애플리케이션인 경우 
       SetLibraryList( ) 함수를 이용하여 라이브러리 찾는 순서를 변경하는 것도 고려
앤시스터 오브젝트가 있는 라이브러리는 처음으로
하위시스템으로 전환시
사용자에 따라 사용하는 부분이 다를 경우 
5.10 
       오브젝트 재생성 
 
구조상 변화 시 재생성
추가나 삭제:
인스턴스나 쉐어드 변수
오브젝트 함수
이벤트 전부
윈도우나 유저오브젝트의 컨트롤
메뉴 오브젝트의 메뉴 아이템
사용자 정의 이벤트 선언이나 삭제 
5.11 
       라이브러리 최적화 
 
한 라이브러리 오브젝트 개수는 
       50 ~ 60 개
한 라이브러리의 크기는 800 
       K
PBL의 조각난 부분을 최적화 하면
개발 시 실행이 빠름
하드디스크 공간을 작게 사용
재생성 후 최적화 
5.12 
       시스템 구성 
 
연장 메모리 사용
메모리 추가
디스크 케싱 사용
배경 그림 비사용 
낮은 해상도 사용
DOS 환경 파일 숙지
CONFIG.SYS
AUTOEXEC.BAT
영구 스왑 파일 사용
스왑 파일을 네트웍 상에 두지는 말 것
하드디스크 조각 모음을 정기적으로
하드드라이브의 속도와 디스크 분할 확인
Windows 
       3.1일 경우 SmartDrive 사용
Windows 환경 파일 숙지
WIN.INI 
         
SYSTEM.INI
되도록 이면 큰 메모리 사용
Windows 3.1: 
         16M
Windows 95 : 32M 
         
개발 시 사용자 환경을 고려
사용자 환경에서 테스트
서버 용량 증대
파워빌더 실행 모듈이 있는 디렉토리는 Path제일 처음 위치로 
읽어보시면 상당히 유용한 내용입니다.

파워빌더 성능 관리
 
근래에 파워빌더로 개발된 곳에서 성능 측정을 요구하는 곳이 많아 지원을 가보면 
일반적으로 고려하여야 할 사항을 무시하고 개발된 곳이 대부분이라 성능이 문제가 되고 있었다.

파워빌더의 문제라기보다는 파워빌더에 맞는 고려사항을 인지하지 못한 탓이다. 
이런 이유로 고객의 요구에 의해 본사에서 시행하는 성능관리 교육교재를 요약하여 싣는다.

(Managing Performance in 
     PowerBuilder)
 
목차 
 
1 장: 
     개요

2 장: 
     해당 실행 모듈 호출

3 장: 
     스크립트 실행 

4 장: 
     데이터 조회

5 장: 
     그 외 사항 
 
1 장: 
     개요
 
성능 이란 
       ?

성능과 관련된 문제점과 토론 사항

성능 향상 정책 수립

사용자 인식 관리

  
 
1.1 
       성능이란 ? 
 
사용자 관점의 성능
성능이라는 것은 실행 시 얼마나 빨리 시스템이 응답하느냐는 것이다. 

개발자 관점의 성능
성능은 다음과 같은 사항을 고려 

서버의 부하
네트웍의 거리
사용자 수
클라이언트와 서버의 구성
데이터베이스 설계와 정규화
애플리케이션의 설계와 작성
사용자의 인지도 
1.2 
       일반적인 성능 불만 사항 
 
윈도우를 열 때 
데이터 조회 시 
애플리케이션 실행 시
필드간 이동 시 
윈도우 간 이동 시
계속하여 실행 시
 
 
1.3 
       문제 발생 요인 
 
해당 실행 모듈 호출
스크립트 실행
데이터 조회
하드웨어와 소프트웨어 구성 
1.4 
       성능 향상 정책 수립 
 
문제점 분리
문제점 범위 지정
이벤트
함수
과정
기능
모든 것이 느리다는 것은 용인되지 않음 
 
 
1.5 
       애플리케이션 환경 점검 
 
애플리케이션의 문제인지 구성 문제인지 ? 
보다 더 성능이 뛰어난 기계에서 실행
관련 모듈을 클라이언트에 설치 
 
 
 
 
1.6 
       설계 재점검 
 
잘못된 설계는 성능에 영향을 미침
기존 프로그램 수정보다는 설계 변경이 효과적 
1.7 
       주의 사항 
 
존재하지도 않는 성능 저하 문제점을 해결하려고 시간 낭비 하지 말 것
뛰어나게 효과가 나지 않을 때는 변경 자제
관리하기 어려운 방식으로 문제 해결하지 말 것 
한번에 많은 변경을 하지 말 것 
 
 
1.8 
       벤치마크 
 
성능을 정량적으로 측정하는 방법
다음 사항을 측정하기 위한 벤치마크 설정
문제점이 실제적으로 성능 저하 요인인가 ?
변경이 성능을 향상 시키는가 ?
주관적인 측정치에 의존하지 말 것 
1.9 
       시간 측정 
 
LONG ll_start, ll_elapsed

// 시작 시간 지정

ll_start = CPU( )

// 측정할 과정 기술

...

// 경과 시간 계산

ll_elapsed = CPU( ) - 
ll_start

파워빌더 
         6.0에서는 프로파일러 이용하여 성능 측정

1.10 
       부하를 이동하거나 분산 
 
긴 작업을 작은 단위로 나눔:
모든 데이터를 조회 후 윈도우를 보여 주는 것 보다는 
윈도우를 먼저 보여 주고 데이터를 가져와서 보여 주는 게 효과적
동일하게 시간이 걸려도 사용자는 덜 지루함 
1.11 
       사용자에게 볼 것을 제공 
 
마우스 포인터 모양 변경
도움말(MicroHelp) 제공
진행과정을 측정기로 보여 줌
취소를 할 수 있게 
 
 
2 장: 
     해당 실행 모듈 호출

모듈 호출

클래스 정의 올리기

관련된 컨트롤과 메뉴 만들기

스크립트 실행

데이터 조회

  
 
2.1 
       모듈 호출 시 영향을 주는 요소 
 
클래스 정의 호출
관련된 컨트롤과 메뉴 생성
스크립트 실행
데이터 조회 
2.2 
       윈도우가 나타나는 과정 
 
클래스 풀에서 해당 모듈을 찾는다.
클래스가 풀에 없으면 라이브러리에서 찾는다. (지정된 라이브러리 순서대로)
윈도우를 생성.
각종 컨트롤을 생성.
관련된 메뉴를 만든다.
각 컨트롤의 Constructor 
       이벤트
윈도우 Open, 
       Activate, Show, Resize 이벤트
스크립트에 있는 데이터 조회 수행
데이터윈도우에 지정된 기능 수행(Sort, Filter..) 
2.3 
       클래스 정의 호출 
 
라이브러리 정비
성능 면이 아닌 관리 측면에서
한번 호출한 것은 등록되어 다시 찾지 않음
각 PBL당 PBD, EXE 모듈은 작게
관련된 모듈끼리 동일 라이브러리에
클라이언트에 파일을 설치 
성능은 향상이 되더라도
분산과 사용자 버전관리가 문제 
2.4 
       관련된 컨트롤과 메뉴 생성 
 
한 윈도우에 컨트롤의 개수를 제한 
       ( 20개)
되도록 이면 데이터윈도우 사용
윈도우 자원 적게 사용
데이터 입력 오류 검증
코드 테이블
드롭다운데이터윈도우
커스텀유저오브젝트 사용 제한
각 컨트롤 수 + 
         1
오브젝트의 크기는 성능에 영향 없음
실행 시 정의되는 인스턴스 변수는 상수로 대치 
2.5 
       재원 
 
사용되는 bmp, 
       ico 등의 PBR은 EXE에 포함 
검색 과정:
EXE - 
         PBD나 DLL - 현재 디렉토리 - 
         \Windows와 \Windows\System 디렉토리 -DOS path
원래 크기 사용
bmp, ico 만 가진 PBD, DLL ? 
2.6 
       필요 시 오브젝트 생성 
 
비즈니스 로직만 가진 유저오브젝트를 만들어 필요 시만 생성하여 사용
데이터스토어가 숨긴 데이터윈도우 컨트롤보다 좋음
OpenUserObject()을 사용하여 필요 시에만 인쇄하는 목적의 데이터스토어 생성
탭 컨트롤에는 CreateOnDemand 
       기능 사용 
2.7 
       상속 
 
상속 다단계는 문제가 되지 않음(메뉴 제외)
상속은 관리나 실행 시 이득
엔시스터의 비대와 상속 다단계는 고려 
2.8 
       클래스 풀 
 
클래스 정의는 클래스 풀에 저장
마지막 인스턴스가 종료되면 지워짐
자주 사용되는 엔시스터 정의는 클래스 풀에 상주시키는 것이 유리 
2.9 
       메뉴 
 
문제점을 분리하기 위해 메뉴를 삭제
각 메뉴 아이템은 오브젝트 하나로 제한고려
탭 컨트롤, 또 다른 윈도우
메뉴 상속은 성능에 악영향 ( 2 ~ 3 단계 ) 
2.10 
       스크립트 수행 
 
문제점을 분리하기 위해 스크립트를 코멘트화
긴 시간 수행 스크립트는 Post
오브젝트 생성시 영향을 주는 이벤트
Open 이벤트
Activate 
         이벤트
각 컨트롤의 Constructor 
         이벤트
GetFocus 
         이벤트
Show와 Resize 
         이벤트 
OpenWithParm()이나 OpenSheetWithParm()으로 윈도우 간에 데이터 교환 시 스트럭춰를 사용하기 보다는 유저오브젝트를 사용
AutoInstantiate 속성은 사용 금지 
2.11 
       메뉴 변경 
 
Hide보다는 
       Disable이 유리
ChangeMenu( ) 
       사용 금지 
2.12 
       데이터 조회 
 
먼저 윈도우를 보여 주고 데이터 조회
조건상 반드시 윈도우와 데이터를 동시에 보여 줄 경우에는 Retrieve As Needed 속성을 지정하고
Open 이벤트에서 Post 
       된 이벤트에 다음과 같은 스크립트를 지정
dw_1.Modify ( 
       ‘DataWindow.Retrieve.asneeded=no’ )
한 화면의 데이터만 필요 하다면
Retrieve As Needed 
       속성을 지정하고
Open 이벤트에서 Post 
       된 이벤트에 다음과 같은 스크립트를 지정
dw_1.DBCancel( 
       )
그 후에 적당하게 Retrieve() 
       함수를 수행 
2.13 Open 
       이벤트는 데이터 조회 삼가 
 
일반적으로 많이 사용되어지는 DDDW는 미리 조회하여 
       ShareData() 함수를 사용하여 공유
사용자가 요청 시에만 데이터 조회를 수행하는 것도 고려 
3 장: 
     스크립트 수행
 
머쉰 코드로 컴파일 

화면 재생성

데이터윈도우 관련 스크립트

루프와 배열

변수

함수와 이벤트

고려할 그 외 사항

  
 
3.1 
       머쉰 코드로 컴파일 
 
장점
변수 참조
수학적 계산이나 할당
로직을 전개하기위한 IF, CHOOSE, FOR, 
         DO 등의 문장 
함수 호출
스크립트에 관련된 사항만 향상
제한 사항
해당 모듈 호출
데이터윈도우 성능
데이터 조회
파워스크립트 함수
예: 
       Retrieve( ) 
함수는 빠르게 호출 되나
서버나 네트웍에는 영향을 미치지 못함 
3.2 
       머쉰코드와 데이터윈도우 기능 
 
파워빌더 5.0과 6.0에서는 다른 문제 해결 방법
데이터윈도우의 “.” 표기
파워빌더 4.0
For 
         ...
li_empid[ll_row] = 
           dw_1.getitemnumber

(ll_row,’emp_id’) 

파워빌더 
       5.0과 6.0
li_empid = 
         dw_1.object.emp_id.current 
3.3 
       화면 재생성 
 
화면 재생성: SetRedraw( ) 
       사용
w_main.SetRedraw(FALSE)
sle_name.Text = 
           ""

sle_address.Show( 
           )

p_photo.PictureName = "photo.bmp"

...

w_main.Title = 
           "Employee Data"

w_main.SetRedraw(TRUE) 
 
3.4 
       단수 속성 참조 
 
Describe( ) 함수
rc = 
         dw_1.describe(“dept_id.x”)
직접 속성 지정
rc = 
         dw_1.object.dept_id.x 
3.5 
       복수 속성 참조(빠른 순서) 
 
복합 
       Describe( ) 함수
modstring = 
         “dept_id.X dept_id.Y” + &
" dept_id.height 
           dept_id.width"

rc=dw_1.Describe( 
           modstring ) 

각각의 
       Describe( ) 함수
각각의 직접 속성 지정
li_x = 
         dw_1.Object.dept_id.X 
3.6 
       단수 속성 지정 
 
Modify( ) 함수
dw_1.Modify( 
         “customer_name.Font.Italic=1”)
직접 속성 지정
dw_1.Object.customer_name.Font.Italic=1 
3.7 
       복수 속성 지정(빠른 순서) 
 
복합 Modify( 
       ) 함수
ls_modstring= 
         "customer_name.Font.Italic=1~t 
customer_city.Color=255"
dw_1.Modify( 
         ls_modstring )
복합 Modify( 
       ) 함수는 SetRedraw( ) 
       사용
직접 속성 지정 시에도 SetRedraw( ) 사용 
3.8 
       데이터 조회 
 
GetItemx( )
ll_id = 
         dw_1.GetItemNumber(1, "emp_id")
직접 참조
ll_id=dw_1.Object.emp_id [1]
GetItemx( ) 가 빠르다.
직접 참조는 블럭 단위 조회 시 유리
예: 
       컬럼 복사
기존 4.0 
         방식: 

string ls_array[ 
         ]
long ll_numrows, 
           i

ll_numrows = 
           dw_1.rowcount ( )

FOR i = ll_numrows 
           to 1 step -1

ls_array [i] = 
           dw_1.GetItemString(i, "emp_name" )

NEXT

5.0과 6.0 방식: 

string ls_array[ 
         ]
ls_array = 
           dw_1.Object.emp_name.Current 
 
3.9 
       데이터 변경 
 
SetItem( )
dw_1.SetItem( 1, 
         "emp_id", ll_id )
직접 변경
dw_1.Object.emp_id 
         [1] = ll_id
SetItem( ) 이 빠르다.
직접 변경은 블럭 단위가 유리. 
3.10 
       데이터윈도우 간의 데이터 공유 
 
반복적으로 조회 불필요
메모리 상에서 데이터 복사는 되도록 회피 
3.11 
       데이터윈도우 간의 데이터 복사 
 
RowsCopy( )
직접 지정
dw_1.Object.Data = 
         dw_2.Object.Data
ImportClipboard( )
ImportString( )
GetItemx( ) / SetItem( ) 
       loop 
3.12 
       선택된 로우만 복사 
 
dw_2.Object.Data = 
       dw_1.Object.Data.Selected
GetSelectedRow( ) 와 RowsCopy( )보다 유리 
3.13 
       데이터윈도우 이벤트 
 
RetrieveRow 이벤트
이벤트 아규먼트 사용
ItemChanged 
         이벤트에서 GetRow() 대신에 Row사용
ItemChanged, EditChanged, 
       ItemFocusChanged, pbm_dwnkey, RowFocusChanged 이벤트에는 되도록 가볍게 작성 
3.14 
       컬럼 이름과 컬럼 번호 
 
컬럼 이름이 관리상 유리
GetItemx( )과 SetItem( )일 경우에는 번호가 조금 빠르고
직접 지정 일 경우에는 번호가 현격하게 빠르다. 
3.15 
       테이블 간의 데이터 이동 
 
데이터파이프라인 사용하는 방법과 데이터윈도우를 중간에 개입하는 방법
데이터파이프라인이 현격하게 빠르다. 
3.16 
       루프와 배열 
 
배열 초기화
intoriginalarray[ 
         ]
intdummyarray[ 
           ]

originalarray = 
           dummyarray 

함수에서 배열을 교환 할 경우에는 Pass by 
       reference나 Read Only 사용
루프내에서 동일한 값을 리턴하는 함수 사용금지
되도록 루프 내에는 작게 작성
이 방식 보다는:
FOR li_index = 1 
         TO UpperBound(li_array)
... 

이방식이 유리:
int 
         li_array_len
li_array_len = 
           UpperBound(li_array)

FOR li_index = 1 
           TO li_array_len

...
 
3.17 
       동적 배열 
 
동적 배열을 사용 할 경우에는 반대로
FOR li_index = 1 
         to li_max
li_array[li_index] 
           = li_index * 10

NEXT 

FOR li_index = 
         li_max to 1 STEP -1
li_array[li_index] 
           = li_index * 10

NEXT 

정적 배열이 동적 배열보다 유리 
3.18 
       변수 
 
참조 시간
Global[t] = 
         Shared[t] 나 Instance[t] * 2
Global[t] = 
         Local[t] * 3
변수 지정 영역
동일 이벤트나 함수 내에서 변수 선언 장소는 문제되지 않음
상수는 개발 시 변수는 실행 시 지정
Any 데이터 타입은 사용 자제 
3.19 
       함수 
 
파워빌더에서 이미 제공하는 함수는 만들지 말 것
해당 오브젝트에 포함되는 함수가 광역 함수보다 유리
지정과 미지정은 동일
wf_save()
Parent.wf_save() 
3.20 
       이벤트와 함수 
 
먼저 성능과는 무관하게 이벤트로 할지 함수로 할지를 결정
4.0과 달리 
       5.0과 6.0에서는 이벤트와 함수가 유사
차이점으로는
이벤트는 오브젝트과만 연관됨
정의되지 않은 함수는 에러 발생
함수는 영역 지정 가능
함수는 찾는 과정이 복잡(외부->광역->오브젝트->앤시스터)
성능 비교(속도가 빠른 순위)
정적 이벤트와 정적 함수
TriggerEvent( ) 
         함수
동적 함수
동적 이벤트 
3.21 
       고려할 그 외 사항 
 
단축 지정 문장이 유리
++, 
         ---
코멘트 삭제
RetrieveRow 
         이벤트에는 되도록 삭제
이벤트
자주 발생하는 이벤트에는 되도록 짧게 작성(MouseMove, 
         Other...)
CHOOSE 
       CASE가 IF / ELSEIF보다 관리면에서 유리
오브젝트 참조 변수
ParentWindow( ) 
         함수를 계속 사용하기 보다는 변수 선언이 유리 
4 장: 
     데이터 조회
 
일반 사항

데이터베이스 설계

SQL 
       튜닝

결과치 감소

데이터 케싱

클라이언트와 서버에 분할

데이터윈도우 오브젝트 실행

  
 
4.1 
       일반 사항 
 
언제 데이터가 필요 한가 
?
반드시 모든 데이터가 필요 한가 
?
결과치를 줄일 수 있는가 ?
설계는 맞는가 ?
데이터베이스 관리자가 관여 하였는가 
       ! 
4.2 
       데이터베이스 연결 최소화 
 
Connect;와 
       DisConnect;를 적절히
SetTrans( 
       )보다는 SetTransObject( ) 사용 
4.3 
       역정규화 
 
정규화 된 데이터베이스는 복잡한 조인을 요구
조인을 줄이기 위하여 역정규화
요약 정보 테이블 생성이 필요 
4.4 
       트랜잭션 관리 
 
COMMIT과 
       ROLLBACK을 적절히 사용하여 서버에서 잡고 있는 자원을 풀어 줌
Retrieve()만 한 경우도 서버의 자원을 잡고 있을 수 있음 
4.5 SQL 
       문장 케싱 
 
반복적인 SQL 문장 
DBParm 속성: Oracle, 
       ODBC
SQLCache=<케쉬하고자 하는 문장 개수>
SQLCache=0 
       케쉬 취소
SQLReturnData를 사용하여 크기 결정
연결 종료 시 케쉬 정보가 들어옴 
4.6 
       바인드 기능 
 
동일한 SQL 문장이고 데이터 값 만 변경이 일어날 경우 한번만 컴파일
DBParm 속성
가 능: DisableBind=1
불가능: 
DisableBind=0
SQLPreview 
       이벤트에서 확인
바인드 적용:
UPDATE department 
         SET dept_name = ?, dept_head_id = ? WHERE dept_id = 
       ?
바인드 비적용:
UPDATE department 
         SET dept_name = ‘Sales’,dept_head_id = 35 
WHERE dept_id = 
         300 
 
 
4.7 
       문제점 분리 
 
SQL 질의를 두 군데에서 
데이터베이스 관리자 페인터
데이터윈도우 페인터
성능이 만족되는가 ?
예: 데이터윈도우 컨트롤의 스크립트를 점검
아니오: SQL 문장 자체를 점검 
4.8 SQL 
       문장은 단순하게 
 
WHERE 절의 
       LIKE를 사용 절제
복잡한 질의를 단순하게 분리
조인은 되도록 삼가 
4.9 
       조인 대신에 DDDW 
       사용 
 
DDDW를 과다하게 사용하면 성능 저하
항상 DDDW가 조인보다 빠른 것이 아님 
4.10 
       데이터윈도우의 변경 속성 조정 
 
WHERE 절이 성능에 지대한 영향
성능이 아닌 동시성과 지속성에 중점 
4.11 
       그 외 SQL 
       관련 사항 
 
스크립트 내에 SQL을 삽입하기 보다는 데이터윈도우나 데이터스토어를 사용
RPC나 스토어드프로시줘를 사용
Explain SQL 
       기능을 이용하여 SQL 질의를 최적화 
 
 
4.12 
       결과치 감소 
 
필요한 데이터만 조회
SELECT * FROM 
         TABLE 금지
조회 취소
결과치 최소화
보고서가 아닌 온라인 조회일 경우 100 건 이상은 현실성 부족
필요한 컬럼을 미리 조회
데이터기 변경이 없다면 데이터윈도우 오브젝트를 데이터와 함께 저장 
4.13 
       하드디스크에 데이터 저장 
 
Rows->Retireve->Rows to Disk 
4.14 
       클라이언트와 서버에 분할 
 
정열
필터링
통계나 계산 
그룹핑
데이터 확인 
4.15 
       데이터윈도우 수행 
 
데이터윈도우는 별도의 엔진을 사용하므로 머쉰코드로 만들더라도 별 효과 없음
데이터윈도우에 지정된 모든 기능은 별도의 데이터윈도우 엔진이 모두 담당
계산 필드, 데이터 확인, 포맷, 정열, 필터 
4.16 
       계산 필드 
 
각 로우 별로 조회 후 계산되므로 성능 저하 요인이 되므로 되도록 계산 컬럼을 사용하는 게 유리 
4.17 
       디스플레이시 영향을 주는 것 
 
슬라이드 컬럼
AutoHeight 
       컬럼
bmp 참조 시
EXE에 포함시키거나
폰트를 활용(Wingding...)
그래프로 데이터표현 시 레이블을 회전시키지는 말 것 
4.18 
       내부 기능 
 
네스티드 데이터윈도우 사용 시에는 케쉬나 바인드 기능을 사용
5.0과 
       6.0에서는 데이터윈도우에 새로운 데이터 형식이 있으므로 해당 형식에 맞게 지정
int
long
real 
4.19 
       조회 전 데이터윈도우와 테이블 비교 
 
파워빌더는 조회 전 데이터윈도우에 정의된 정보와 테이블의 내용이 일치하는지 미리 조사 한 후 조회
DBParm 속성 지정
결과치 비교 조사 취소: 

SQLCA.DBParm = 
         'StaticBind=1'
 

결과치 비교 조사 : 
         

SQLCA.DBParm = 
         'StaticBind=0' 
5 장: 
     그 외 사항
 
애플리케이션 성능 저하

애플리케이션 여는 시간

포커스 이동

DDDW가 늦게 열림

윈도우 활성

라이브러리 관리

시스템 구성

  
 
5.1 
       애플리케이션 성능 저하 
 
열었으면 닫아야 함
생성했으면 제거도 하여야 함
OpenUserObject( 
       )을 사용하였으면 CloseUserObject( )도 기술
OpenTab( ) 
       을 사용하였으면 CloseTab( ) 도 기술
연결하였으면 연결 종료도 하여야 함 
5.2 
       변수 선언 없이 생성 
 
변수 선언 없이 유저오브젝트를 생성하지 말 것
n_trans = CREATE 
         n_trans
문장 상으로 문제는 없으나 계속적으로 필요 없는 것이 생성됨 
5.3 
       애플리케이션 열기 
 
애플리케이션 시작 시에 다음에 필요한 작업을 하는 것도 고려 해 볼만 함
데이터베이스 연결 및 초기화
코드 테이블 조회
보안
만약에 애플리케이션 여는 시간이 문제라면 메인 윈도우에서 처리 
 
 
5.4 
       데이터윈도우 컬럼 간 이동 
 
ItemChanged 
       이벤트
ItemFocusChanged 
       이벤트
RowFocusChanged 
       이벤트
데이터 검증 룰
계산 필드
조건부 수행 
5.5 
       컨트롤 간 이동 
 
LoseFocus 
       이벤트
GetFocus 
       이벤트 
5.6 
       포커스 이동 시 문제점 해결 
 
중요하지 않은 과정은 Post
스크립트 수정
데이터 조회 시점 변경
데이터윈도우 오브젝트 점검
앤시스터 스크립트 확인 
5.7 
       DDDW가 늦게 열림 
 
각 DDDW가 각각 조회하는 것보다는 공유
pbm_dwndropdown 
       이벤트 점검 
5.8 
       윈도우 활성 
 
윈도우 활성이 늦으면 Activate, DeActivate 이벤트를 점검
시간이 걸리는 데이터조회는 
         Post
Activate 
         이벤트에 메뉴 관련 로직은 삼가
쉬트를 관리하기 위한 로직이 Activate 이벤트에 있다면 GetFirstSheet( ), 
         GetNextSheet( ), GetActivateSheet() 함수로 대치하여 전개 
5.9 
       라이브러리 관리 
 
대규모 애플리케이션인 경우 
       SetLibraryList( ) 함수를 이용하여 라이브러리 찾는 순서를 변경하는 것도 고려
앤시스터 오브젝트가 있는 라이브러리는 처음으로
하위시스템으로 전환시
사용자에 따라 사용하는 부분이 다를 경우 
5.10 
       오브젝트 재생성 
 
구조상 변화 시 재생성
추가나 삭제:
인스턴스나 쉐어드 변수
오브젝트 함수
이벤트 전부
윈도우나 유저오브젝트의 컨트롤
메뉴 오브젝트의 메뉴 아이템
사용자 정의 이벤트 선언이나 삭제 
5.11 
       라이브러리 최적화 
 
한 라이브러리 오브젝트 개수는 
       50 ~ 60 개
한 라이브러리의 크기는 800 
       K
PBL의 조각난 부분을 최적화 하면
개발 시 실행이 빠름
하드디스크 공간을 작게 사용
재생성 후 최적화 
5.12 
       시스템 구성 
 
연장 메모리 사용
메모리 추가
디스크 케싱 사용
배경 그림 비사용 
낮은 해상도 사용
DOS 환경 파일 숙지
CONFIG.SYS
AUTOEXEC.BAT
영구 스왑 파일 사용
스왑 파일을 네트웍 상에 두지는 말 것
하드디스크 조각 모음을 정기적으로
하드드라이브의 속도와 디스크 분할 확인
Windows 
       3.1일 경우 SmartDrive 사용
Windows 환경 파일 숙지
WIN.INI 
         
SYSTEM.INI
되도록 이면 큰 메모리 사용
Windows 3.1: 
         16M
Windows 95 : 32M 
         
개발 시 사용자 환경을 고려
사용자 환경에서 테스트
서버 용량 증대
파워빌더 실행 모듈이 있는 디렉토리는 Path제일 처음 위치로



감사히 잘 읽겠습니다.
출처 : http://www.softpackage.com/bbs/bbs/content.asp?grp=devforum&board=pbuilder&num=44&opt=
Posted by SB패밀리
파워빌더에서 DEBUG나 RUN을 모드에서 실행시의 속도와
Deploy를 통한 어플리케이션 모드에서 실행시의 속도가 다른 경우가 발생하는데
여기에 대한 질문과 답변예를 살펴보자.


질문1)

10.0으로 파워빌더를 업그레이드 하기 전에 트라이얼 버전으로 문제가 없는지 체크를 하고 있습니다. 저희 시스템이 기존에 7.0으로 개발이 되어있는 상태였는데요 pb 9버전으로 마이그레이션 후 pb10.0으로 마이그레이션 하고 테스트를 진행 했습니다. 마이그레이션은 에러없이 정상적으로 되었구요.. 소스에서 실행 했을때 문제 없이 작동도 잘 됩니다. 그런데 문제는 컴파일을 했을때 인데요.. 프로그램을 실행후에 Window가 Open되는데 25초 이상이 걸립니다. 그 후에도 프로그램의 실행 속도가 엄청나게 느려지고 프로그램의 기능도 소스에서와 다르게 작동을 합니다. 이런 현상을 글로써 설명하기가 굉장히 힘이 든데요. 소스로 테스트 했을때와 컴파일 후에 다르게 실행이 된다는것이 이상하구요. 7.0에서는 아무 문제없이 쓰던 소스 그대로 인데 이렇게 되는게 이상합니다. 그래서 pb 10.0이 문제 인가 해서 pb 9.0에서 컴파일을 했는데요 역시 마찬가지 현상이 나타납니다.

답변)

질문 내용을 보았을때 속도가 느려지는 것은  10으로 마이그레이션 해서 그런것이 아니라 라이브러리 리스트 구조상 무언가 잘못지정되어 있는 것이 있는게 아닌가 싶습니다. 예를 들어 실제 오픈 되는 윈도우가 있는 PBL가 이 윈도우가 참조하는 다른 오브젝트가 다른 PBL에 있는데 이 PBL경로가 다른 폴더에 있거나... 아니면 오픈되는 윈도우가 계승을 받은 윈도우 인데...조상 윈도우의 라이브러리 위치가 뒤에 있거나, 이런 부분을 조정을 해 보시기 바랍니다.


질문2)
파워빌더로 현재 어플리케이션을 개발중입니다.
현업에서 어플리케이션 실행 시 속도가 너무 느려 점검해본 결과 파워빌더에서 소스 실행시와 어플리케이션(실행파일)에서 실행 시에 DB 연결 속도 차이가 무려 10배 이상 나고 있습니다. 아직 데이터 건수가 많지 않아 조회 시 속도가 느린지는 확인되지 않고 있습니다.
이런 현상이 일어나는 원인이 무엇이며, 해결책이 있는지 알고 싶습니다.
참고로 기타 인터넷 속도등은 전용망이기 때문에 잘 나오고 있습니다.
답변)
개발툴과 실행파일 사이에는 이미 로드된것을 이용하는것과 안하는것의 차이가 있습니다.
개발 툴에서 실행시 데이터베이스 연결은 물론 필요한 Object들이 이미 메모리에 로드되어 있어서 말씀하신 속도의 차이를 보일 수 있습니다.
하지만 이러한 속도는 실행 모듈에서 어플케이션이 실행되고 나면 조회에 있어서는 같은 속도를 유지 해야 됩니다.
만약 데이터 조회에 있어서도( DB 연결 후) 말씀하신 속도의 차이가 있으면 어딘가에 문제가 있다고 볼수 있습니다.
또한 어플리케이션 Open 시 과도한(사용하지 않는) 오브젝트를 로드한다든가 LIbrary Path 마지막에 있는 오브젝트를 로드하는 방법은 많은 시간을 소요할 수 있습니다. 그러므로 일반적으로 어플리케이션이 Open 시 사용되는 Object는 어플리케이션과 같은 PBL에 위치를 시키고, 실행 파일 만들때 이 pbl만 pbd Check를 빼서 속도를 최대화 하실 수 있습니다. 

 

Posted by SB패밀리
DataWindow Object Reference
출처: http://manuals.sybase.com/onlinebooks/group-pbarc/@Generic__CollectionView;lang=ko

DataWindow.Print property

Print.property

Description

Properties that control the printing of a DataWindow.

Applies to

DataWindows

Syntax

PowerBuilder dot notation:

dw_control.Object.DataWindow.Print.property

Describe and Modify argument:

"DataWindow.Print.property { = value }"

SyntaxFromSQL:

DataWindow ( Print.property = value )

Parameter

Description

property

A property for printing. Properties and their settings are listed in the table below

value

The value to be assigned to the property. Value cannot be a DataWindow expression

Property for Print

Value

Collate

Whether printing is collated. Note that collating is usually slower since the print is repeated to produce collated sets. Values are:

  • Yes -- Collate the pages of the print job

  • No -- (Default) Do not collate

The user can specify the value in the system's Print dialog box if the printer driver supports it

Color

An integer indicating whether the printed output will be color or monochrome. Values are:

  • 1 -- Color

  • 2 -- Monochrome

The user can specify the value in the system's Print dialog box if the printer driver supports it

Columns

An integer specifying the number of newspaper-style columns the DataWindow will print on a page. For purposes of page fitting, the whole DataWindow is a single column. The default is 1

Painter: Newspaper Columns Across option

Columns.Width

An integer specifying the width of the newspaper-style columns in the units specified for the DataWindow

Painter: Newspaper Columns Width option

Copies

An integer indicating the number of copies to be printed

The user can also specify this value in the system's Print Setup dialog box if the printer driver supports it

If you use both the Print.Copies property and the Print Setup dialog box to indicate that multiple copies should be printed, the total number of copies printed is the product of both values

DocumentName

A string containing the name that will display in the print queue when the user sends the contents of the DataWindow object to the printer

Painter: Document Name option

Duplex

An integer indicating the orientation of the printed output. Values are:

  • 1 -- Simplex (none)

  • 2 -- Horizontal

  • 3 -- Vertical

The user can specify the value in the system's Print dialog box if the printer driver supports it

Filename

A string containing the name of the file to which you want to print the report. An empty string means send to the printer

Painter: Not settable in painter

Margin.Bottom

An integer indicating the width of the bottom margin on the printed page in the units specified for the DataWindow

You can set Margin.Bottom when using SyntaxFromSQL to generate DataWindow syntax.

Painter: Bottom Margin option

Margin.Left

An integer indicating the width of the left margin on the printed page in the units specified for the DataWindow

You can set Margin.Left when using SyntaxFromSQL to generate DataWindow syntax

Painter: Left Margin option

Margin.Right

An integer indicating the width of the right margin on the printed page in the units specified for the DataWindow

You can set Margin.Right when using SyntaxFromSQL to generate DataWindow syntax

Painter: Right Margin option

Margin.Top

An integer indicating the width of the top margin on the printed page in the units specified for the DataWindow

You can set Margin.Top when using SyntaxFromSQL to generate DataWindow syntax

Painter: Top Margin option

Orientation

An integer indicating the print orientation. Values are:

  • 0 -- The default orientation for your printer

  • 1 -- Landscape

  • 2 -- Portrait

Painter: Paper Orientation option

Page.Range

A string containing the numbers of the pages you want to print, separated by commas. You can also specify a range with a dash. For example, to print pages 1, 2, and 5 through 10, enter: "1,2, 5-10". The empty string means print all

The user can specify the value in the system's Print dialog box if the printer driver supports it

Page. RangeInclude

An integer indicating what pages to print within the desired range. Values are:

  • 0 -- Print all

  • 1 -- Print all even pages

  • 2 -- Print all odd pages

The user can specify the value in the system's Print dialog box if the printer driver supports it

Paper.Size

An integer indicating the size of the paper that will be used for the output:

  • 0 -- Default paper size for the printer

  • 1 -- Letter 8 1/2 x 11 in

  • 2 -- LetterSmall 8 1/2 x 11in

  • 3 -- Tabloid 17 x 11 inches

  • 4 -- Ledger 17 x 11 in

  • 5 -- Legal 8 1/2 x 14 in

  • 6 -- Statement 5 1/2 x 8 1/2 in

  • 7 -- Executive 7 1/4 x 10 1/2 in

  • 8 -- A3 297 x 420 mm

  • 9 -- A4 210 x 297 mm

  • 10 -- A4 Small 210 x 297 mm

  • 11 -- A5 148 x 210 mm

  • 12 -- B4 250 x 354 mm

  • 13 -- B5 182 x 257 mm

  • 14 -- Folio 8 1/2 x 13 in

  • 15 -- Quarto 215 x 275mm

  • 16 -- 10x14 in

  • 17 -- 11x17 in

  • 18 -- Note 8 1/2 x 11 in

  • 19 -- Envelope #9 3 7/8 x 8 7/8

  • 20 -- Envelope #10 4 1/8 x 9 1/2

  • 21 -- Envelope #11 4 1/2 x 10 3/8

  • 22 -- Envelope #12 4 x 11 1/276

  • 23 -- Envelope #14 5 x 11 1/2

  • 24 -- C size sheet

  • 25 -- D size sheet

  • 26 -- E size sheet

  • 27 -- Envelope DL 110 x 220mm

  • 28 -- Envelope C5 162 x 229 mm

  • 29 -- Envelope C3 324 x 458 mm

  • 30 -- Envelope C4 229 x 324 mm

  • 31 -- Envelope C6 114 x 162 mm

  • 32 -- Envelope C65 114 x 229 mm

  • 33 -- Envelope B4 250 x 353 mm

  • 34 -- Envelope B5 176 x 250 mm

  • 35 -- Envelope B6 176 x 125 mm

  • 36 -- Envelope 110 x 230 mm

  • 37 -- Envelope Monarch 3.875 x 7.5 in

  • 38 -- 6 3/4 Envelope 3 5/8 x 6 1/2 in

  • 39 -- US Std Fanfold 14 7/8 x 11 in

  • 40 -- German Std Fanfold 8 1/2 x 12 in

  • 41 -- German Legal Fanfold 8 1/2 x 13 in

Painter: Paper Size option

Paper.Source

An integer indicating the bin that will be used as the paper source. The integer you use depends on the tray number used by the printer. (To determine the actual bin setting, you can query the printer with a utility that makes API calls to the printer driver). Typical values are:

  • 0 -- Default

  • 1 -- Upper

  • 2 -- Lower

  • 3 -- Middle

  • 4 -- Manual

  • 5 -- Envelope

  • 6 -- Envelope manual

  • 7 -- Auto

  • 8 -- Tractor

  • 9 -- Smallfmt

  • 10 -- Largefmt

  • 11 -- Large capacity

  • 14 -- Cassette

Painter: Paper Source option

Preview

Whether the DataWindow object is displayed in preview mode. Values are:

  • Yes -- Display in preview mode

  • No -- (Default) Do not display in preview mode

Preview.Rulers

Whether the rulers display when the DataWindow object displays in preview mode:

  • Yes -- Display the rulers

  • No -- (Default) Do not display the rulers

You can view rulers in Preview mode in the DataWindow painter. Choose File>Print Preview, then File>Print Preview Rulers. However, the setting is not used at runtime. To see rulers during execution, set Print.Preview.Rulers in code

Preview.Zoom

An integer indicating the zoom factor of the print preview. The default is 100%

You can view different zoom percentages in Preview mode in the DataWindow painter. Choose File>Print Preview, then File>Print Preview Zoom. However, the setting is not used at runtime. To change the zoom factor during execution, set Print.Preview.Zoom in code

Prompt

Whether a Printer Setup dialog displays before a job prints so the user can change the paper or other settings for the current printer. Values are:

  • Yes -- (Default) Display a Printer Setup dialog

  • No -- Do not display a Printer Setup dialog

Choosing Cancel in the Printer Setup dialog dismisses the Setup dialog; it does not cancel printing. To allow the user to cancel printing, see the Print method.

For DataStores, this property is ignored; a dialog is never displayed.

Painter: Prompt Before Printing checkbox

Quality

An integer indicating the quality of the output. Values are:

  • 0 -- Default

  • 1 -- High

  • 2 -- Medium

  • 3 -- Low

  • 4 -- Draft

The user can specify the value in the system's Print dialog box if the printer driver supports it

Scale

An integer specifying the scale of the printed output as a percent

The scaling percentage is passed to the print driver. If you have problems with scaling, you may be using a driver that does not support scaling

The user can specify the value in the system's Print dialog box if the printer driver supports it

For more information, see your print driver documentation

Usage

In the painter

Select the DataWindow by deselecting all controls; then set values in the Properties view, Print Specifications tab.

Examples

Example 1

ls_data = dw_1.Object.DataWindow.Print.Scale

Example 2

dw_1.Object.DataWindow.Print.Paper.Size = 3

Example 3

ls_data = dw_1.Describe("DataWindow.Print.Scale")

Example 4

dw_1.Modify("DataWindow.Print.Paper.Size = 3")

Example 5

dw_1.Modify("DataWindow.Print.Margin.Top=500")
Posted by SB패밀리

원문 : http://cafe.naver.com/pbdn/16

Datawindow control 에 포커스를 준 상태에서( 데이터를 선택 ) Ctrl+MouseWheel 을
이용하여 스크롤을 하면 데이터윈도우가 Zoom-in, Zoom-out 이 됩니다.
이것은 7.0 부터 생긴 기능입니다.

이 기능을 막고자 한다면 다음과 같이 사용하시면 됩니다.

Datawindow Control 의 other event 에 아래의 스크립을 이용하면
zoom 기능이 동작 하지 않습니다.

-------------------------------------------------------
other event
-------------------------------------------------------
CONSTANT integer WM_MOUSEWHEEL = 522

IF message.number = WM_MOUSEWHEEL AND &
    KeyDown (KeyControl!) THEN
  message.processed = TRUE
  RETURN 1
END IF 
Posted by SB패밀리


wininet.dll 를 이용한 ftp 방법이네요

자료실에 적지 않은 소스가 올라와 있지만

wininet.dll를 이용하여 한눈에 볼수 있게 올리셨으니

더 많이 이용할 것 같네요

고맙습니다 ^^


//먼저 global external function에서 선언하시고
 
FUNCTION ULONG InternetConnectA (ULONG hInternetSession, STRING sServerName, INT nServerPort, STRING sUsername, STRING sPassword, ULONG lService, ULONG lFlags, ULONG lContext) LIBRARY "wininet.dll"
FUNCTION ULONG InternetOpenA (STRING sAgent, LONG lAccessTyp, STRING sProxyNam, STRING sProxyBypass, ULONG lFlags) LIBRARY "wininet.dll"
FUNCTION ULONG InternetCloseHandle (ULONG hInet) LIBRARY "wininet.dll"
FUNCTION ULONG FtpOpenFileA (ULONG hFtpSession, STRING sBuff, ULONG Access, ULONG FLAGS, ULONG Context) LIBRARY "wininet.dll"
FUNCTION ULONG FtpGetFileSize (ULONG hFile, ULONG lpdwFileSizeHigh) LIBRARY "wininet.dll"
FUNCTION ULONG InternetReadFile (ULONG hFile, REF BLOB sBuffer, ULONG lNumBytesToRead, REF LONG dwNumberOfBytesRead) LIBRARY "wininet.dll" 
FUNCTION ULONG InternetWriteFile (ULONG hFile, REF BLOB sBuffer, ULONG lNumBytesToWrite, REF LONG dwNumberOfBytesWritten) LIBRARY "wininet.dll"

 
//다음 global variable에서 선언하세요
 
CONSTANT LONG ERROR_NO_MORE_FILES = 18
CONSTANT LONG BUFFERSIZE = 255
CONSTANT LONG INTERNET_FLAG_PASSIVE = 134217728
CONSTANT LONG FTP_TRANSFER_TYPE_BINARY = 2
CONSTANT LONG FTP_TRANSFER_TYPE_ASCII = 1
CONSTANT LONG GENERIC_READ = 2147483648
CONSTANT LONG GENERIC_WRITE = 1073741824
CONSTANT LONG INTERNET_OPEN_TYPE_PRECONFIG = 0
CONSTANT LONG INTERNET_SERVICE_FTP = 1
 
CONSTANT STRING IP="210.91.117.9"
CONSTANT INT PORT=3001
CONSTANT STRING ID="CHEIL"
CONSTANT STRING PW="NBS"
 
CONSTANT STRING CONNECTS="PASSIVE"
CONSTANT STRING TRANSFER="BINARY"
CONSTANT STRING SERVER="/"
 
CONSTANT STRING PATH="c:\erp"
CONSTANT STRING DEVICE="c:"
 
LONG GL_HOPEN, GL_HCONNECTION, GL_HFILE, GL_DWTYPE, GL_DWSEMAN
STRING GS_SYSID, GS_PGID, GS_EXT, GS_VER
 
BOOLEAN GB_CYCLE = TRUE 
 
//다음 화일 다운로드(업로드)시에 아래의 3개의 함수를 사용하세요
//호출시 FTP를 OPEN합니다
FTPOPEN(IP, PORT, ID, PW)
 
//다운로드 받습니다
FTPDOWNLOAD("c:\a.txt", "/a.txt", 1000)
 
//FTP를 종료합니다
FTPCLOSE()

 
//아래는 FTPOPEN함수 부분입니다
//4개인 인수가 있는데 순서대로 string,integer,string,string type 입니다

TRY
 IF GL_HCONNECTION < 0 THEN INTERNETCLOSEHANDLE(GL_HCONNECTION)
 
 YIELD()
 GL_HOPEN = INTERNETOPENA("FTP MODULE",INTERNET_OPEN_TYPE_PRECONFIG, ' ', ' ', 0)
 GL_HCONNECTION = INTERNETCONNECTA(GL_HOPEN,IPS,PORTS,USER,PASSWORD,INTERNET_SERVICE_FTP,GL_DWSEMAN,0)
CATCH (RUNTIMEERROR RE)
 SLE_4.TEXT = "FTP 연결오류"
END TRY
 
IF GL_HCONNECTION < 0 THEN RETURN TRUE
 
//아래는 FTPDOWNLOAD 부분입니다
//3개의 인수가 있는데 순서대로 string,string,integer 입니다

BLOB LB_DATA
LONG LL_SUM, LL_BLOCK, LL_DWREAD
INT LI_FILENUM
 
YIELD()
 
TRY
 IF NOT ISNULL(LOCAL) AND NOT ISNULL(REMOTE) THEN
 GL_HFILE = FTPOPENFILEA(GL_HCONNECTION, REMOTE, GENERIC_READ, GL_DWTYPE,0)
 
 IF GL_HFILE =0 THEN
 SLE_4.TEXT = "FTP 화일열기 실패 : " + GS_PGID
 RETURN FALSE
 END IF
 
 SIZE = FTPGETFILESIZE(GL_HFILE,0)
 IF SIZE <= 0 THEN RETURN FALSE
 
 HPB_1.Maxposition = INT(SIZE / BUFFERSIZE)
 LL_SUM = 0
 
 YIELD()
 
 LI_FILENUM = FILEOPEN(LOCAL, STREAMMODE!, WRITE!, LOCKWRITE!, REPLACE!)
 FILESEEK(LI_FILENUM, 0, FROMBEGINNING!)
 
 FOR LL_BLOCK = 1 TO INT(SIZE / BUFFERSIZE)
 YIELD()
 
 LB_DATA = BLOB(SPACE(BUFFERSIZE))
 IF INTERNETREADFILE(GL_HFILE,LB_DATA,BUFFERSIZE,LL_DWREAD) = 0 THEN
 SLE_4.TEXT = "FTP 화일읽기 실패 : " + GS_PGID
 RETURN FALSE
 END IF
 
 FILEWRITE(LI_FILENUM, LB_DATA)
 
 LL_SUM += BUFFERSIZE
 HPB_1.POSITION = INT(LL_SUM / BUFFERSIZE)
 NEXT
 END IF
 
 LB_DATA = BLOB(SPACE(MOD(SIZE,BUFFERSIZE)))
 IF INTERNETREADFILE(GL_HFILE,LB_DATA,MOD(SIZE,BUFFERSIZE),LL_DWREAD) = 0 THEN SLE_4.TEXT = "FTP 화일읽기 실패 : " + GS_PGID
 
 FILEWRITE(LI_FILENUM, LB_DATA)
 HPB_1.POSITION = HPB_1.MAXPOSITION
 
 YIELD()
 
 INTERNETCLOSEHANDLE(GL_HFILE)
CATCH (RUNTIMEERROR RE)
 SLE_4.TEXT = "FTP 화일전송 실패 : " + GS_PGID + GS_EXT
END TRY
 
FILECHECK()
SLE_3.TEXT = "전송화일 : " + GS_PGID + GS_EXT
RETURN TRUE 

 
//여기서 ftpgetfile 함수를 사용하지 않고 internetreadfile 함수를
//사용한 이유는 프로그래스바에서 진행상황을 나타내기 위함입니다
 
//마지막으로 FTPCLOSE 함수부분입니다
 
IF GL_HCONNECTION < 0 THEN INTERNETCLOSEHANDLE(GL_HCONNECTION)
GL_HCONNECTION = 0 
 

이정도만 하면 완변하게 구현이 되는데 single text 나 프로그래스바
컨트롤은 설치하신후에 프로그램해야 오류가 안난다는것은 말할 필요가
없겠죠..

출처: http://www.pbdn.net/board/BoardShow.aspx?board_id=2&role=qna&page=4&c_id=7663&c_seq=5&sfield=total&svalue=wininet
고맙게 잘 봤습니다.

추가... 직접 작성한 화일 업로드 루틴 추가



//아래는 FTPUPLOAD 부분입니다
//2개의 인수가 있는데 순서대로 string,string입니다
BLOB LB_DATA
LONG LL_SUM, LL_BLOCK, LL_DWWRITE , LL_SIZE
INT LI_FILENUM
 
YIELD()
 
TRY
 IF NOT ISNULL(a_local) AND NOT ISNULL(a_remote) THEN
  GL_HFILE = FTPOPENFILEA(GL_HCONNECTION, a_remote, GENERIC_WRITE, GL_DWTYPE,0)
 
  IF GL_HFILE =0 THEN
   MessageBox('FTP', "FTP 화일쓰기 실패 1: " + GS_PGID )
   RETURN FALSE
  END IF
  
  //a_SIZE = FTPGETFILESIZE(GL_HFILE,0)
  LL_SIZE = FileLength(a_local)
  IF LL_SIZE <= 0 THEN
   RETURN FALSE
  END IF
  //HPB_1.Maxposition = INT(SIZE / BUFFERSIZE)
  LL_SUM = 0
  
  YIELD()
  
  LI_FILENUM = FILEOPEN(a_LOCAL, STREAMMODE!, READ!, LOCKWRITE!, REPLACE!)
  FILESEEK(LI_FILENUM, 0, FROMBEGINNING!)
  
  FOR LL_BLOCK = 1 TO INT(LL_SIZE / BUFFERSIZE)
   YIELD()
   
   LB_DATA = BLOB(SPACE(BUFFERSIZE))
   IF INTERNETWRITEFILE(GL_HFILE,LB_DATA,BUFFERSIZE,LL_DWWRITE) = 0 THEN
    MessageBox('FTP', "FTP 화일쓰기 실패 2: " + GS_PGID )
    RETURN FALSE
   END IF
   
   FILEREAD(LI_FILENUM, LB_DATA)
   
   LL_SUM += BUFFERSIZE
   //HPB_1.POSITION = INT(LL_SUM / BUFFERSIZE)
  NEXT
 END IF
 
 FILEREAD(LI_FILENUM, LB_DATA)
 
 //LB_DATA = BLOB(SPACE(MOD(LL_SIZE,BUFFERSIZE)))
 IF INTERNETWRITEFILE(GL_HFILE,LB_DATA,MOD(LL_SIZE,BUFFERSIZE),LL_DWWRITE) = 0 THEN
  MessageBox('FTP', "FTP 화일쓰기 실패 3: " + GS_PGID )
 END IF 
 //FILEWRITE(LI_FILENUM, LB_DATA)
 //HPB_1.POSITION = HPB_1.MAXPOSITION

 YIELD()

 INTERNETCLOSEHANDLE(GL_HFILE)

CATCH (RUNTIMEERROR RE)
 MessageBox('FTP', "FTP 화일보내기 실패 4: " + GS_PGID + GS_EXT )
END TRY
 
//FILECHECK()
MessageBox('FTP', "보내는화일 : " + GS_PGID + GS_EXT )
RETURN TRUE 
 

Posted by SB패밀리


파워빌더 11.5 버전 테스트


FTP서버에 파일을 Upload, Download, Delete, 목록가져오기 등을 구현하는 예제입니다.

해당 Zip파일을 풀면 ftp.dll과 이 dll을 파워빌더에서 API로 사용하는 방법이 설명되어 있는 파일, 그리고 이를 구현한 PB n.v.o가 PBL에 있습니다.

ftp.dll은 system32폴더 또는 파워빌더 실행파일이 있는 위치에 두시면
됩니다.


[ftp1.pbl]
------------------------------------------------------------------------
// FTP
n_ftp in_ftp

// FTP UPload

string is_server, is_user, is_pass, is_serverfilename, is_clientfilename


is_server = a_server
is_user = a_user
is_pass = a_pass
is_serverfilename = a_serverfilename
is_clientfilename = a_clientfilename

    // 1. FTP object 생성
    in_ftp    = create n_ftp 

    // 2. FTP Connect
    Int li_i
    li_i = in_ftp.FTPConnect(is_server, is_user, is_pass)

    if li_i <> 0 then
       MessageBox("오류", "FTP Server에 접속중 오류가 발생했습니다.", Exclamation!)
       destroy in_ftp
       return
    end if

    // 3. FTP Transfer
    Int li_rtn
    string s_server_file, s_client_file
    s_server_file = is_serverfilename //"c:\\test.txt"
    s_client_file = is_clientfilename //"/tmp/test"

    // 송신 put
    li_rtn = in_ftp.FTPputFile(s_client_file, s_server_file, 0)

   
    /* -ftp의 사용법------------------------------------------------------------
    FTPgetCurrentDir ( return string(blob) ) 
    FTPsetCurrentDirUp ()
    FTPsetCurrentDir ( "디렉토리")
    FTPfileList ( return string(blob) )
    FTPgetFile ( String REMOTE_FILE, String LOCAL_FILE, integer BINARY_OR_TEXT )
    FTPcreateDir ( String NEW_DIR )
    FTPdeleteFile ( String DEL_FILE )
    FTPdeleteDir ( String DEL_DIR )
    FTPrenameDir ( String CURR_DIR, String NEW_DIR )
    FTPputFile ( String LOCAL_FILE, String REMOTE_FILE, integer BINARY_OR_TEXT )
    FTPping ( String IPaddress )
    ------------------------------------------------------------------------- */   

    if li_rtn = 0 then
       //Transfer Success..
        MessageBox("안내", "파일전송 성공!")
    else
       //Transfer Failure..
       MessageBox("안내", "파일전송 실패!")
       return
    end if

    // 4. FTP Disconnect
    Int li_rtn2
    li_rtn2 = in_ftp.FTPDisconnect()
    if li_rtn2 <> 0 then
       MessageBox("오류", "FTP Disconnect를 하는 중에 오류가 발생했습니다.", Exclamation!)
       destroy in_ftp
       return
    end if

    // 5. FTP Close
    destroy in_ftp

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

출처 : 구글 검색
고맙게 잘 봤습니다.

Posted by SB패밀리

이벤트에서 트랩될 수 있는 시스템 에러

Error.Number

Error.Text

1

0으로 나눔

2

참조할 오브젝트가 Null 임

3

배열의 영역이 초과됨

4

열거된 값이 함수의 범위를 벗어남

5

함수에서 음수값을 반환함

6

지정된 행/열에 데이터윈도우가 맞지 않음

7

외부 연결을 참조할 때 해결되지 않은 문제가 있음

8

널 스크립트를 가진 배열을 참조함

9

현재 애플리케이션에 DLL함수가 없음

10

DLL함수에 지원되지 않는 인자형이 있음

12

GetItem형과 DataWindow의 열 타입이 맞지 않음

13

속성 참조를 해결하지 못함

14

외부 함수에서 DLL 라이브러리를 열 때 에러 발생

15

외부 함수를 호출할 때 에러 발생

16

최대 스트링 크기를 초과함

17

D/W 오브젝트에서 참조한 데이터윈도우가 존재하지 않음

18

함수가 변환값을 갖지 않음

19

변수에서 이름을 바꿀 수 없음

20

데이터베이스 명령어가 성공적으로 준비되지 않았음

21

파일 참조 실행시간 에러

22

오브젝트 타입이 틀림

23

오브젝트의 타입이름을 변수의 타입이름으로 표시할 수 없음

24

함수 호출이 정의와 맞지 않음

25

Double형이나 실수형의 표현이 오버플로우됨

26

필드 이름 지정을 지원하지 않음

27

정수의 제곱에 음수를 가질수 없음

28

VBX에러 : 이름

30

외부오브젝트 테이터 타입의 이름을 지원하지 않음

31

지원되지 않는 외부 오브젝트 데이터형의 이름

32

외부 함수 호출시 이름을 찾을 수 없음

33

외부 오브젝트 함수 호출시 인자형이 맞지 않음

34

외부 오브젝트 함수 호출시 인자의 개수가 맞지 않음

35

외부 오브젝트 속성의 호출시 에러

36

외부 오브젝트 속성을 접근하는데 찾는 이름이 없음

37

외부 오브젝트 속성을 접근하는데 타입이 맞지 않음

38

외부 오브젝트 속성을 접근하는데 하위스크립트의 수가 부정확함

39

외부 오브젝트 속성을 접근하는데 에러 발생

40

자료형이 맞지 않음

41

문법에 맞지 않는 이상한 자료형이 있음

42

DLL 함수를 호출하는데 지정한 인자형과 필요한 인자형이 다름


애플리케이션 종료 에러

Error.Number

Error.Text

50

애플리케이션 참조를 해결할 수 없다

51

동적 라이브러리를 로드 하는데 실패

52

조상 오브젝트의 이름이 빠짐

53

이름에서 조상 오브젝트의 이름이 빠짐

54

이름에서 조상 오브젝트의 이름과 이름이 충돌함

55

요청된 함수를 수행하던 중에 윈도우 닫음 발생

56

데이터베이스 인터페이스가 원격 프로시저 호출을 지원하지 않음

57

데이터베이스 인터페이스가 배열함수(함수이름)를 지원하지 않음

58

이름을 위한 BLOB변수가 비었음

59

최대 길이를 초과

[출처] [펌] 에러코드|작성자 구우

Posted by SB패밀리
데이타윈도우 내용을 엑셀로 내려받기
 
  데이타윈도우의 데이타를 엑셀로 내려받을때 컬럼명이 영문으로 나오는 것을 볼
수 있습니다.
 
  화면에서의 컬럼명처럼 엑셀파일에서도 한글컬럼명이 보여지기를 원할 때 다음과
같이 작성하시면 원하는 결과를 얻을 수 있습니다.
 
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)
Posted by SB패밀리

MessageBox PowerScript Function

사용자가 정의한 title, text, icon, buttonMessageBoxDisplay한다.

MessageBox (title, text , icon, button , default )

Parameter Description

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

title Message boxtitle bar에 지정한 문자열이 나타난다.
text
사용자가 원하는 textMessage boxDisplay한다.
text
numeric 자료형, string, boolean 값이 가능하다
Icon icon의 값은 사용자가 원하면 Message box의 왼쪽에 display하려는 icon들을 가리키는 data type들을 열거한다.

* Information! (Default)
* Stopsign!
* Exclamation!
* Question!
* None!

button 사용자가 display하려는 CommandButtonmessagebox하단에 setting하고
command button을 가리키는 data type을 열거한다.
버튼들은 열거된 데이타 타입의 순서로 번호붙여진다..

(optional)

* OK! - (Default) OK button
* OKCancel! - OK and Cancel buttons
* YesNo! - Yes and No buttons
* YesNoCancel! - Yes, No, and Cancel buttons
* RetryCancel! - Retry and Cancel buttons
* AboutRetryIgnorel - About, Retry, and Ignore buttons

default button의 번호는 default button으로 사용할 수 있다.
(optional) default1이고, 만약 사용자가 지정한 번호가 displaybutton 번호 이상이면 , MessageBoxdefault로 이용한다.




반환값

Integer 성공했다면 지정한 번호 (1, 2, 3)을 return 하고,

실패인경우 -1를 return한다.

title 이나 text 의 값이 null 이면, MessageBox 는 보여지지않는다.

사용자가 지정하지 않으면 파워빌더는 사용자가 버튼을 클릭하거나 엔터를 누를 때 스크립트 실행을 계속한다. 이것은 MessageBox가 버튼을 하나 가지고 있을 때 적합하다. 버튼이 많으면 스크립트안에 리턴값을 체크하고, 적합한 조치를 취하는 스크립트에 코드를 포함시켜야한다.

현재의 application 을 계속하기 전에 사용자는 MessageBox에 응답해야한다. 그러나, 사용자는 MessageBox에 응답하지 않고 다른 aplication으로 바꿀수 있다.

MessageBox"Greeting","Hello User" default icon, default button을 보여준다.
MessageBox("Greeting", "Hello User")

다음 문장은 함수의 결과와 exclamation iconOKCancel 버튼을 포함한 Result라는 제목의 MessageBoxdisplay한다.

integer Net
long Distance = 3.457

Net =
MessageBox("Result", Abs(Distance), & Exclamation!, OKCancel!, 2)

IF Net = 1 THEN
  ... // process OK
ELSE
  ... // Process CANCEL.
END IF



출처 : http://cafe.daum.net/pbcraft/3NoU/40?docid=7Zna|3NoU|40|20011102000753&q=%C6%C4%BF%F6%BA%F4%B4%F5%20MessageBox%20%B8%AE%C5%CF&srchid=CCB7Zna|3NoU|40|20011102000753

Posted by SB패밀리



Q) 데이터윈도우의 컬럼이 a1 ~ a50까지 있습니다.
   여기서 데이터윈도우를 Retrieve()후 특정 Row의 특정컬럼의 값이 'A'일 경우
   이 'A'가 속한 컬럼명을 얻는 방법 좀 알려주세요..

A) 해당 컬럼명을 얻어 오는 방법은 아래 스크립트를 참고하시면 됩니다.
    ======================================================
        String ls_column, ls_original_border, ls_temp

        IF NOT dwo.name = "datawindow" then //DWObject 바탕을 클릭!
        IF dwo.band = "header" THEN
            IF dwo.name = "" THEN
           Messagebox("Error", "칼럼 헤더 오브젝트에 칼럼명이 없습니다.")
           Return
          END IF
        ls_column = Left(dwo.name, Pos(dwo.name,"_t") -1 )
        MessageBox('선택한 컬럼의 이름', ls_column)
  END IF
END IF
======================================================

Q) 버전관리프로그램을 개발중입니다.

   pbd파일을 DB에 저장할려고 image 형식으로 정했습니다.
   pb에서 FileOpen시 streamMode이면 파일사이즈 크기가 32764로 한정되어 있는데
   칼럼형식을 무엇으로 정해야 DB에 저장할수 있는지 조언을 바랍니다. DB서버는 oracle 9i를

   사용하고 있습니다
   Oracle Client 를 9i 로 사용하다가 oracle client 8i 로 변경 하였습니다 (oracle client 9i 삭제 후

   8i로 재설치)
   9i로 설정해서 PB를 사용할때는 잘 되다가 8i로 바꿔서 설치하고 나서는 connection 이 안되네요
   connection 할때 나오는 오류메시지는 아래와 같습니다
   답변 부탁드립니다
  ▶▶ 6. 오류메시지 ◀◀
    Please connect as the PowerBuilder Catalog Owner. This is necessary for
    the initial connection to Oracle to GRANT privileges on the repository.

A)  Database profile 에 DB 연결하는 곳을 보시면 System 이란 Tab 이 있습니다.
     해당 Tab 에 catalog owner 가 SYSTEM 이 Default 일 텐데..
     사용하고 계시는 Owner 정보가 다른것 같습니다. 이 부분을 수정하시기 바랍니다.


Q) 파워빌더에서 최기는 오라클로 접속하고, retrieve된 데이라를 가지고,
    sql에 접속하여, 데이터를 이관하는 프로그램 입니다.
    파워빌더에서 실행했을때는 에러가 나질 않는데, 실행파일을 만들고, 실행하면,
    오라클은 연결되는데, sql에는 접속이 안됩니다.
     1. 오라클 접속정보(application에서 )
         SQLCA.DBMS = "O84 ORACLE 8.0.4"
         SQLCA.LogPass = "xxxx"
         SQLCA.ServerName = "xxxx"
         SQLCA.LogId = "xxxx"
         SQLCA.AutoCommit = False
         SQLCA.DBParm = ""
         CONNECT USING sqlca;

     2. sql접속정보( open-> retrieve 후 )
          Sqlca2 = create transaction

          SQLCA2.DBMS = "ODBC"
          SQLCA2.AutoCommit = False
          SQLCA2.DBParm = "ConnectString='DSN=xxxxx;UID=xxxxxx;PWD=xxxxx'"
        
  ▶▶ 6. 오류메시지 ◀◀

   Database에 연결할 수 없습니다. 9999DBMS ODBC is not supported in your current insatllation
  
A)  먼저, 두개이상의 트렌젝션을 생성하여 사용할때는 혼동될 소지가 있기 때문에
     SQLCA를 사용하시는것 보단, trans_ora, trans_odbc 등의 특정이름으로 사용하시는

     것이 좋습니다.
    첨부파일로 PB7에서 필요한 DLL들을 정리해놓은 문서를 올려드립니다.
    참고하시기 바랍니다.
    문서에는
        PBODB70.DLL : 파워빌더 ODBC 인터페이스
        PBOR870.DLL : 오라클 8 DLL
        등의 내용이 정리되어 있습니다.
    또한, 현재 파우빌더 8 버전까지 기술지원이 종료된 상태(2006년 8월 31일)입니다.
    8이하 버전은 글 읽기 권한만 가지게 됩니다.

Q) dw안에 check box 컬럼이 있습니다
  이 체크박스 컬럼을 클릭할때 마다 몇개의 Row의 채크박스컬럼이 선택되어졌는지 표시할려고

  하는대 방법을 알려주시기 바랍니다
  클릭이벤에 다음과 같이 사용하였습니다
     long i, j
     for i = 1 to this.rowcount() step 1
      if this.getitemstring(i,"bal") = "1" then
        j = j + 1
      END IF  
     next
     st_1.text = String(j) + "행이 선택되었습니다"

  
A) Clicked() 이벤트에 스크립트를 작성하면 스크립트가 먼저 실행되어 버리고
     화면에 체크가 되어지기 때문에 처음 체크했을때의 값은 가져오지 못하고
     두번째 아이템을 체크할때부터 인식되어 지게 되는 현상이었습니다.
    해결방법은....
     작성하신 스크립트를 Post 방식으로 호출하면 해결하실수 있습니다.
     ue_clicked()를 하나 만들고 DW의 Clicked() 이벤트에
       Post Event ue_clicked()
     처럼 호출해주면 원하는 결과를 얻으실수 있습니다. Test 해보시기 바랍니다.

Q) 데이타윈도우 삭제를 했는데도 pbl사이즈만 자꾸 늘어납니다.
   export, import 반복하다보니 현재 25메가가 되었는데요..
  실행시 메모리 부족하다는 영문 메시지와 함께 파빌이 다운되어버립니다.
  그리고 해당 소스 들어갈때도 100번에 95번은 에러가 나는데 에러가 나고
  다운이 되면 그 소스 다신 안 들어가집니다.
  하던 개발작업을 못하고 있습니다.
  
A)  현재 사용하고 계신 것에 많은 제약사항이 있네요.
     첫째, XP 는 PowerBuilder 8.0.3 이상에서만 보장되어 집니다.
     둘째, 아시겠지만, 해당 PBL 의 사이즈가 엄청나게 크군요.. PowerBuilder 에서 보장하고,
     권장하는 하는 PBD 의 size 는 2 MB 입니다.
     일단, 25 MB 짜리를 갈려서 하시는게 좋을듯합니다. 보장이 안되니까.. 어떨땐 되고, 어떨 때는
    안되는 것입니다.
     export, import 가 자주 있다고 하셧는데 이러한 경우, 해당 PBL 에서 오른쪽 마우스를 누르시면
     Optimize 라는 것이 있습니다. 이것을 통해 최적화를 하십시요.
     size 가 조금 줄어 들 것입니다.
     하지만, 근본적인 해결책이 되지 않으며, Source 의 size 에 대한 것은 지키시고, OS 에

     따른 PB 버전도 생각하시기 바랍니다.

Q) temp3 = 84.5
  gyesanhak = 20
  pyongjum = round(temp3 / gyesanhak, 2)
  위와같은 식이 있을때 당연히 pyongjum은 4.23이 나와야 합니다.  4.225에서 반올림하므로...
  하지만 pyongjum의 형식이 double이면 4.22가 됩니다.
  이것을 decimal형식으로 선언을 하면 4.23이 되구요...
  
A) Double 과 Real 과 같은 부동소수점 데이터 타입은 원래 정확한 값을 기억하지 못합니다.

    4.225 값을 저장 시켜도 4.2249999999999999 와 같이 인식하기 때문에 round 하지
   못한거구요. 이 문제는 비단 파워빌더 뿐만 아니라, 다른 언어도 마찬가지입니다.
   이 문제에대한 자세한 내용은 아래를 참고하세요.
     http://www.sybase.com/detail?id=1012599

Q) 3 tier 방법으로 개발하려고 합니다.

   그래서 서버단, 클라이언트단 나누어서 배포를 하고 작업하는데요...
   클라이언트에서 서버단의  컴포넌트에 있는 함수를 콜하면 자꾸 에러메시지가 떨어집니다.
   이런 메시지 는 어떻게 나는거고 해결은 어떻게 해야할지...
   오류메시지를 첨부파일로 올립니다..
   더불어서  제규어에서 패키지를 지웠는데도 프럭시 생성시 지워지지 않은것처럼 클라이언트 쪽에

   프럭시가  생성이 되네요.. 이유가 무엇인지.. 정말 모르겠습니다.

A) 우선 클라이언트단 로직은 정상적으로 서버컴포넌트를 호출하는 것으로 보입니다.  

    서버컴포넌트 로직 수행 중 에러가 발생되면 질문하신 것 처럼     "CORBA_TRANSACTION_ROLLEDBACK" 에러가 Display 됩니다.

    때문에, 정확한 원인을 파악하기 위해서는 서버 Log 를 확인 해서 에러가 발생된 위치를 찾고,

    해당 컴포넌트의 로직을 확인해 봐야합니다.

    만약 서버단에 에러가 발생되더라도 이를 클라이언트에 Display 하고싶지 않다면,

    해당 컴포넌트 속성중 tx_outcome 값을 failed 로 설정 하시면 됩니다.
     com.sybase.jaguar.component.tx_outcome = failed

Q)  아래와 같이 프로시져를 생성하고 데이타 윈도우를 만들었는데 데이타윈도우 내에서 조회는

  되는데 run 해서 실행해면 윈도우에서 rtn = dw_List.Retrieve(ls_Fund_Cd) retrieve를 하면
  pls-00306 호출시 인수의 갯수나 유형이 잘못되었습니다. 라는 오류 메세지가 나옵니다.
  데이타윈도우에 Argument는 한개이고요 프로시져는 아래와 같습니다.
  CREATE OR REPLACE procedure sr_ops_fd_0001r_01 ( p_fund_cd in varchar2,
  out_cur OUT pkg_cursor.cur_out) is BEGIN
   -----------------------------------------------------------------
     begin
   -----------------------------------------------------------------
  Open out_cur FOR
SELECT A.FUND_CD       FUND_CD,
   A.FUND_NM   FUND_NM,
   A.TYPE_GB   TYPE_GB,
   A.FIR_SEOLJ_YMD   FIR_SEOLJ_YMD,
   A.FIR_GIJUNGA   FIR_GIJUNGA,
   A.WT_BOSUYUL   WT_BOSUYUL,
   A.PM_BOSUYUL   PM_BOSUYUL,
   A.ST_BOSUYUL   ST_BOSUYUL,
   A.SM_BOSUYUL        SM_BOSUYUL,
   A.WT_BOSUYUL + A.PM_BOSUYUL + A.ST_BOSUYUL + A.SM_BOSUYUL   tot_bosuyul,
   DECODE(A.MULTI_CLS_GB, '1', '일반', '2', '상위', '3', '하위', '')     MULTI_CLS_GB,
   decode(A.ILIM_GB,'01','일임','02','손익','03','MMF','4', '자문', '')   ILIM_GB,
   D.EMP_NM   EMP_NM,
   A.PRV_STK_LOWLMT_WGT   PRV_STK_LOWLMT_WGT,
   A.PRV_STK_HIGHLMT_WGT   PRV_STK_HIGHLMT_WGT,
   B.MAEMAE_NM   MAEMAE_NM,
   TO_CHAR(A.sanghw_ymd, 'YYYYMMDD')   sanghw_ymd
  FROM   COM_FM0_M A,
   COM_MM0_C B,
   COM_EF0_M C,
   COM_EM0_M D
WHERE  A.SUTAK_CD = B.MAEMAE_CD
AND    A.FUND_CD = C.FUND_CD
AND    A.EMP_ID = C.EMP_ID
AND    'Y' = C.RPRS_MGR_GB
AND    A.EMP_ID = D.EMP_ID
AND    A.FUND_CD LIKE p_fund_cd
ORDER BY A.FUND_NM;
-----------------------------------------------------------------
  end;
-----------------------------------------------------------------
--<<process_end>>
END;
▶▶▶ 6. 오류메시지 ◀◀◀
  pls-00306 호출시 인수의 갯수나 유형이 잘못되었습니다.

A) 파워빌더 개발환경에서 DB연결하는 사용자ID와 실제 실행환경에서 DB연결할 때 사용되는

    사용자ID가 서로 다른 것 같습니다. 실행환경에 사용된 사용자ID는 pkg_cursor 에 접근할 수

    없는 사용자로 생각됩니다. 파워빌더 DB Profile 의 사용자와 sqlca.UserID 사용자
    정보를 동일하게 맞춰주면 해결할 수 있을겁니다.

Q)  5,0 라이센스 시디를 가지고 있습니다.
   근데 5,3 라이센스 CD 라던가 패치파일을 받고 싶은데 자료실에 없던데요..
   sybase 본사 인터넷에서 직접 받아야 되나요?
  
A)  답변의 첨부파일을 받아서 설치하시면 됩니다.
     설치시 주의사항은 5.0이 설치되어 있어야 합니다. (아래글 참조)
     ===============================================
      Enclosed you will find updated EAServer software. You must install this
      upgrade over EAServer 5.0 or higher. If you have an earlier version, upgrade
      to EAServer 5.0 or higher before installing EAServer 5.3
     ===============================================
     압축을 풀면 Redeme 파일이 있습니다. 먼저 읽어보신후 패치하시기 바랍니다

Q) Appeon을 도입하려고 준비중인데....
   테스트로 commandline을 이용해서 활용 예제를 만들어 보고 있습니다.
   http://xxx.xxx.xxx:9988/text/index.html?xxxxx
   이런식으로 웹페이지를 호출을 하는데요
   새로 열린 브라우저 타이틀에 호출 URL이 그대로 노출이 되는 것 같은데요(XP에서)
   해결방안이 없나요
   CommandLine(?xxxxx) 정보가 노출되면 안되거든요..숨길 수 있는 방법은?
   그리고 Appeon FAQ에 있는 내용중에 application이 종료되면 웹브라우저도 같이 종료되는

   예제가 있는데요
   CommandLine을 사용한 예제도 부탁을 드립니다.
     y = Long(ls_y) + 438

A)  1. Anchor 태그를 이용한 호출( http://xxx.xxx.xxx:9988/text/index.html?xxxxx )로는

          직접적으로 URL이 보이는 것을 막을 수가 없습니다.
         중간에 자바스크립트로 Anchor 태그를 호출하는 것을 하나 만들어서 사용자가 클릭하였을

         때 자바스크립트를 호출하시고 자바스크립트에서 Anchor태그를 이용하여 호출하거나 또는

         Anchor 태그로 넘겨야 하는 값을 Session 정보에 저장한 다음 Appeon에서 Session에

        있는 값을 읽어 오는 형태로 작업을 하셔야 할 것입니다.
      2. 저희 팀 홈페이지에 있는 자바스크립트를 이용한 Blank 페이지 종료하는 예제를

         이용하시면 됩니다.

Q)  윈도우 user events 추가시 항목의 event id별 활용설명서를  볼 수 있는지요    

A)     일단.. xp 를 사용하시려면, PowerBuilder 8.0.3 이상의 버전이셔야 합니다.
     Event ID 는 pbm_ 로 시작하고 ( PowerBuilderMessage ) 입니다.
     이것은 WM_ 로 시작하는 Event id 값과 1:1 로 매핑되어집니다.
     따라서 pbm_xxx 에 있는 것을 WM_XXX 로 생각하셔서, MSDN 에서 찾아보시면 됩니다.

Q)  오라클 8에서 잘 실행되던 프로그램인데 db를 9.2.0으로 올리고 나서 에러가 납니다
  ▶▶▶ 6. 오류메시지 ◀◀◀
  String ls_company, ls_date, ls_no, ls_name, ls_dept_name

  DECLARE isp_slip_no PROCEDURE FOR ac_user.ac_sp_slip_no
  (:ls_company, :gs_dept, :ls_date);

ls_date = as_date
  ls_company = Upper( Left(gs_comp_unit, 1) )

  IF gf_isdate(ls_date) THEN
  execute isp_slip_no;

  FETCH isp_slip_no
  INTO :ls_no;
  CLOSE isp_slip_no;

  SELECT dept_name
  INTO :ls_dept_name
  FROM ac_dept
  WHERE dept_code = :gs_dept;

  dw_1.SetItem(al_row, "slip_no", ls_no)
  dw_1.SetItem(al_row, "slip_row", '001')
  dw_1.SetItem(al_row, "input_user_id", gs_user)
  // dw_1.SetItem(al_row, "pe_v_employee_name", gs_user_name)
  dw_1.SetItem(al_row, "ccom_slip_user_name", gs_user_name)
  dw_1.SetItem(al_row, "ac_dept_code", gs_dept)
  dw_1.SetItem(al_row, "ac_dept_dept_name", ls_dept_name)    

     새로 오라클9 에 생성한 사용자 권한이 오라클8 사용자 권한과 다른 것 같습니다.
     첨부하신 내용처럼, ac_user.ac_sp_slip_no 프로시저를 호출하지 못하기 때문에
     발생되는 에러입니다. 담당 DBA와 상의해보시기 바랍니다.

A)  현재사용중인 파워빌더6.0을 9.0으로 마이그레이션 하였고 데이타베이스도 정상적으로
   CONNECT하였습니다.
   그런데 file -> new ->에서 datawindow object를 만들려고하면 첨부된 내용처럼 에러가 생깁니다.
   다시 삭제하고 재설치해도 마찬가지입니다.
   기존에 6.0에서사용했던 datawindow object를 copy하여 9.0에서 open하여도 마찬가지입니다.
  도무지 이유를 모르겠습니다.  
  

A)   이런 경우는 DLL이 꾜여서 발생하는 경우가 대부분입니다.
     먼저 DLL들이 정확하게 올라오는지 확인해보시기 바랍니다.
     DLL이 올라오는 것을 확인하는 방법은, 저희 핼프시스템에서 많이 다룬 내용입니다.
     검색에서 "제목+내용"으로 winmsd 를 검색하시면,많은 내용을 볼수 있습니다.
     -------------------------------------------------------------------------------
     PowerBuilder를 실행시키고, 로드된 모듈을 체크해 보시기 바랍니다. (각 버전 밑 위치 확인)
   * 체크 방법
    시작-> 실행 -> winmsd -> 소프트웨어 환경 -> 로드된 모듈
    그러면 로드된 소프트웨어에 가보시면, 파워빌더 관련 dll 들이 있는데. 여기 나오는 모든 버전이
    일치해야 하며 경로 또한 동일해야 합니다
    (program filessybaseShearedPowerBuilder  여기가 default 입니다)
    아울러, 파워빌더를 제거 하실때, 레지스트리 정리 까지 하시는 것을 권장합니다.


Q)   버전관리프로그램을 개발중입니다.
   pbd파일을 DB에 저장할려고 image 형식으로 정했습니다.
   pb에서 FileOpen시 streamMode이면 파일사이즈 크기가 32764로 한정되어 있는데
   칼럼형식을 무엇으로 정해야 DB에 저장할수 있는지 조언을 바랍니다.

A)  파일의 사이즈가 32764 로 한정되어 있는 것이 아니라 FileRead 함수가 한번에 읽을 수 있는
     크기가 32765 로 제한되어 있는 것 입니다. 32765 가 넘는 크기에 대해서는 루프를 돌면서
    읽어서 처리해야 합니다. 아래의 코드(파워빌더 헬프에 있는 예제)를 보시면 쉽게 이해하실 수
    있을 것입니다.
    컬럼형식은 image 나 기타 binary data 를 처리할 수 있는 형식으로 하시면 됩니다.
    컬럼형식에 대한 보다 자세한 내용은 데이터베이스 도움말을 참조하시기 바랍니다.

     integer li_FileNum, loops, i
     long flen, bytes_read, new_pos
     blob b, tot_b

     // Get the file length, and open the file
     flen = FileLength(sle_filename.Text)
     li_FileNum = FileOpen(sle_filename.Text, &
        StreamMode!, Read!, LockRead!)

     // Determine how many times to call FileRead
     IF flen > 32765 THEN
        IF Mod(flen, 32765) = 0 THEN
            loops = flen/32765
        ELSE
            loops = (flen/32765) + 1
        END IF
     ELSE
        loops = 1
     END IF

     // Read the file
     new_pos = 1

     FOR i = 1 to loops
        bytes_read = FileRead(li_FileNum, b)
        tot_b = tot_b + b
     NEXT

   FileClose(li_FileNum)
Posted by SB패밀리