2012년 12월 6일 목요일

하단기사 입력 프로그램

하단기사 입력프로그램 수정내역
* 책제목으로 검색하는기능이 추가되었습니다.
자동입력시 중단하는 기능을 추가했습니다

2012년 10월 13일 토요일

ipconfig /all 명령으로 맥어드레스 가져오기

function RunDosCommand : string; var hReadPipe : THandle; hWritePipe : THandle; SI : TStartUpInfo; PI : TProcessInformation; SA : TSecurityAttributes; SD : TSecurityDescriptor; BytesRead : DWORD; Dest : array[0..8192] of Ansichar; CmdLine : array[0..1024] of char; TmpList : TStringList; S, Param : string; Avail, ExitCode, wrResult : DWORD; begin { Dos Application } InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(@SD, True, nil, False); SA.nLength := SizeOf(SA); SA.lpSecurityDescriptor := @SD; SA.bInheritHandle := True; CreatePipe(hReadPipe, hWritePipe, @SA, 4096); try Screen.Cursor := crHourglass; FillChar(SI, SizeOf(SI), 0); SI.cb := SizeOf(TStartUpInfo); SI.wShowWindow := SW_HIDE; SI.dwFlags := STARTF_USESHOWWINDOW; SI.dwFlags := SI.dwFlags or STARTF_USESTDHANDLES; SI.hStdOutput := hWritePipe; SI.hStdError := hWritePipe; StrPCopy(CmdLine, 'ipconfig /all'); if CreateProcess(nil, CmdLine, nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, SI, PI) then begin ExitCode := 0; while ExitCode = 0 do begin wrResult := WaitForSingleObject(PI.hProcess, 500); if PeekNamedPipe(hReadPipe, nil, 0, nil, @Avail, nil) then begin if Avail > 0 then begin FillChar(Dest, SizeOf(Dest), 0); ReadFile(hReadPipe, Dest, Avail, BytesRead, nil); Result := StrPas(Dest); Application.ProcessMessages; end; end; if wrResult <> WAIT_TIMEOUT then ExitCode := 1; end; GetExitCodeProcess(PI.hProcess, ExitCode); CloseHandle(PI.hProcess); CloseHandle(PI.hThread); end; finally CloseHandle(hReadPipe); CloseHandle(hWritePipe); Screen.Cursor := crDefault; end; end; function GetMacAddress : string; var i : Integer; sList, tList : TStringList; begin sList := TStringList.Create; tList := TStringList.Create; ExtractStrings([#13],[], PChar(RunDosCommand), sList); for i := 0 to sList.Count - 1 do begin if (Pos('물리적 주소', sList[i]) > 0) or (Pos('Physical Address', sList[i]) > 0) then begin tList.Clear; ExtractStrings([':'], [], PChar(sList[i]), tList); // ':' 로 나눈 뒤에 것이 MAC Address if Length(Trim(tList[1])) = 17 then begin Result := Trim(tList[1]); Exit; end else Result := 'Could not found'; end; end; end; 위의 두 펑션을 추가한뒤 다음과 같이 사용한다. 버튼의 커멘드에서

2010년 8월 8일 일요일

[파워빌더]CSV 포멧으로 파일저장하기

long i,rno,rcnt
string cdate,ccomp,item,header_str,chango,damdang,uprice,qty,price,tax,tprice,pay
string docname, named,w_string,groupname
integer value

header_str = '출고일자,출고처,단체명,제품명,단가,출고량,금액,세액,합계,결재금액,창고명,담당자'
value = GetFileSaveName("Select File", docname, named, "CSV", &
"Comma Seperated Format(*.CSV),*.CSV," + " Text Files (*.TXT), *.TXT")
IF value = 1 THEN
integer li_FileNum
li_FileNum = FileOpen(docname,LineMode!, Write!, LockWrite!, Replace! )
FileWrite(li_FileNum, header_str)
rcnt = dw_1.rowcount()
uo_2.hpb_1.minposition = 0
uo_2.hpb_1.maxposition = rcnt
uo_2.visible = true
for i = 1 to rcnt
cdate = string(dw_1.object.idate[i],'yyyy-mm-dd')
ccomp = dw_1.object.customer_company[i]
groupname = dw_1.Describe("Evaluate('LookUpDisplay(group_no)'," + string(i) + ")")
item = dw_1.object.item_item[i]
uprice = string(dw_1.object.iuprice[i])
qty = string(dw_1.object.isize[i])
price = string(dw_1.object.itotal[i])
tax = string(dw_1.object.tax[i])
tprice = string(dw_1.object.iuprice[i] * dw_1.object.isize[i])
pay = string(dw_1.object.ipay[i])
chango = dw_1.object.storeroom_cname[i]
damdang = dw_1.object.e_name[i]
if isnull(cdate) then cdate = ''
if isnull(ccomp) then ccomp = ''
if isnull(groupname) then groupname = ''
if isnull(item) then item = ''
if isnull(uprice) then uprice = ''
if isnull(qty) then qty = ''
if isnull(price) then price = ''
if isnull(tax) then tax = ''
if isnull(tprice) then tprice = ''
if isnull(pay) then pay = ''
if isnull(chango) then chango = ''
if isnull(damdang) then damdang = ''
w_string = cdate + ',' + ccomp + ',' + groupname + ',' + item + ',' + uprice + ',' + qty + ',' + price + ',' + tax + ',' + &
tprice + ',' + pay + ',' + chango + ',' + damdang
FileWrite(li_FileNum, w_string)
uo_2.hpb_1.position = i
next
FileClose(li_FileNum)
uo_2.visible = false
messagebox('자료생성',string(rcnt) + '건의 자료가 생성되었습니다.')
dw_1.setredraw(true)
end if

2010년 8월 7일 토요일

[파워빌더]2개 이상의 DataWindow의 크기 조절

굴림//-. Window위에 나란히 배치된 2개 이상의 DataWindow의 크기 조절
// 화면을 디자인하다 보면 윈도우 탐색기의 중앙분리막대처럼
// 한쪽이 커지면 한쪽이 작아지게 하는 기능이 필요할 때가 있다.
// 아쉽게도 PowerBuilder에는 그런 기능을 하는 Object는 없다.
// 그렇게 되는 것처럼 보이도록 디자인을 하고 Program을 작성해야 한다.
//
// w_form이라는 Window위에 dw_1과 dw_2라는 DataWindow Object가 2개 있다고 가정하자.
// dw_1은 왼쪽에 dw_2는 오른쪽에 위치하고 dw_1의 폭이 확대되면 dw_2의 폭은 줄어든다.
// 반대로 dw_2의 폭이 확대되면 dw_1의 폭은 줄어든다.
//
// 1. w_form위의 적당한 위치에 StaticText Object를 하나 놓는다. st_1이라 하자
// 2. st_1의 Property에서 [Pointer] Tab을 선택한 뒤 SizeWE! (↔)를 선택하자.
// 3. st_1에 User Event를 몇 개 추가한다.
// -. mousemove : pbm_mousemove를 추가한다.
// -. mousedown : pbm_lbuttondown을 추가한다.
// -. mouseup : pbm_lbuttonup을 추가한다.
//
// 4. w_form에 윈도우 함수를 하나 추가한다.

// function prototype : void w_resize( void )
long ll_Max
ll_Max = dw_2.X + dw_2.Width // dw_2의 오른쪽 끝지점
dw_1.Width = st_1.X - ( dw_1.X + 2)
dw_2.X = st_1.X + 10 // st_1의 두께를 8로 보고 dw_1과 dw_2사이를 12로 본다.
dw_2.Width = ll_Max - dw_2.X // dw_2의 폭은 오른쪽 끝지점에서 X좌표를 빼준다.

// 5. st_1에 아래와 같은 Script를 구성한다.

// constructor EVENT for st_1
This.X = (dw_1.X + dw_1.Width + 2)
This.Y = dw_1.Y
This.Height = dw_1.Height
This.Width = 8
This.BackColor = Parent.BackColor
dw_2.X = (dw_1.X + dw_1.Width + 14 )

//mousemove EVENT for st_1
// 왼쪽버튼을 누른 상태로 움직인다면 마우서 커서를 따라서 움직이도록 한다.
IF KeyDown( KeyLeftButton! ) Then
This.X = Parent.PointerX()
End If

// mousedown EVENT for st_1

// 마우스로 찍으면 시각적으로 표시되도록 한다.
This.BackColor = RGB( 0, 0, 0 )

//mouseup EVENT for st_1
// 마우스를 떼면 안보이게 한다.
This.BackColor = Parent.BackColor
// dw_1을 벗어나 너무 오른쪽으로 가는 것을 방지한다.
IF This.X < ( dw_1.X + 500 ) Then
This.X = dw_1.X + 500
END IF
// dw_2를 벗어나 너무 왼쪽으로 가는 것을 방지한다.
IF This.X > ( (dw_2.X + dw_2.Width) - 500 ) Then
This.X = (dw_2.X + dw_2.Width) - 500
End IF

// 데이타윈도우 크기를 조절한다.
wf_resize()

2010년 8월 4일 수요일

임베디드파이어버드

임베디드파이어버드는 dll한개로만 사용할수있는 로컬 데이타베이스입니다.

사용방법은 너무간단합니다.

1.자신의 방에 이렇게 db엔진을 복사를 해줍니다.
D:\my_app\fbembed.dll
D:\my_app\gds32.dll (renamed fbembed.dll) <-- 이부분이 중요합니다.
D:\my_app\fbclient.dll (renamed fbembed.dll) <-- 이부분이 중요합니다.
D:\my_app\firebird.conf
D:\my_app\isql.exe
D:\my_app\ib_utils.dll
D:\my_app\firebird.msg
D:\my_app\intl\fbintl.dll

파이어버드 임베디드 2.0에서는 다음 세개의 파일이 추가로 더 필요합니다.
icudt30.dll, icuin30.dll, icuuc30.dll

2.firebird.conf파일을 편집을 해주셔야 합니다.
다른내용을 수정할꺼 없구 이것 한개만 수정해주시면 됩니다.
RootDirectory = D:\my_app


3.cmd에서 자신의방(D:\my_app\)의 isql을 실행시키고 사용하시면 됩니다.

4.델파이에서 사용하는 방법
개발은 기존의 인터베이스 커넥션을 그대로 사용하셔서 개발을 하시구
배포시에만 자신경로에 1번의 예라면 D:\my_app\ 여기에
실행파일만 포함시키면 끝입니다.

제가 테스트는 dbexpress드라이버,zeos 5.x,zeos 6.x,ibx,fibplus를 테스트해봤는데
아주 잘붙네요..

5.인터베이스 관리툴을 임베디드엔진에 붙이기.
ibexpert나 ems의 ibmanager의 아이콘을 한개를 바탕화면에 복사를 하시고
실행위치만 D:\my_app\로 바꾸면 성공입니다..

임베디드 엔진이 mysql도있는데
개발이나 배포측면에서 임베디드mysql보다 조금더 쉬운것 같네요..

FireBird Database Connection

//uses에 UniDAC관련 클래스 추가
Uses
Uni, InterBaseUniProvider, DBAccess;
//데이터베이스 컨넥션
procedure ConnectDatabase;
var
StrParm : TStringList;
begin
uConn := TUniConnection.Create(nil);
with uConn do begin
Database := 'D:\DelphiWork\Completed\NSourceMan\SOURCEMAN.FDB';
Username := 'SYSDBA';
Password := 'masterkey';
LoginPrompt := False;
ProviderName := 'InterBase';
Connected := True;
end;
dbProvider := TInterBaseUniProvider.Create(nil);
uTrans := TUniTransaction.Create(nil);
uTrans.DefaultConnection := uConn;
end;

2010년 8월 3일 화요일

FastReport를 사용하여 출력하기

1. frxReport콘트롤을 폼위에 올려 놓는다.
2. 미리보기창이 최대창으로 나타나는것을 방지하기위해 PreviewOptions에서 Maximized속성을 False로 한다.
3. 나머지는 모두 기본값으로 나둔다.

1. frxDBDataset컴포넌트를 폼위에 올려 놓는다.
2. CloseDataSource만을 False로 바꾸고 나머지는 그대로 둔다.
3. ReportDesigner에 나타나는 이름을 구분하고 싶으면 UserName속성에서 이름을 바꾼다.

데이터연결

출력버튼에 다음과 같이 스크립트를 작성한다.
dbgCheckResult.Enabled := False;
frxDBCustomer.DataSet := dbCname.DataSource.DataSet;
frxDBDataset1.DataSet := dbgCheckResult.DataSource.DataSet;
frxReport1.ShowReport;
dbgCheckResult.Enabled := True;

데이터소스는 이미 활성화되어 있는 그리드 또는 필드의 값에서 데이터셋을 구해온 후
frxDBDataset에 연결한다.

레포트폼 디자이너에서 해당 필드를 넣고 필드명을 데이터소스와 같이 만들어준다.
1. 텍스트 필드를 도구에서 선택하여 폼위에 올려 놓는다.
2. 텍스트 필드의 DataSet속성에서 연결된 frxDBDataset을 선택하고
3. DataField 속성에서 실제 데이터베이스의 필드명을 입력한다.

만일 여러개의 데이터셋이 필요하면 필요에 따라 여러개의 데이터셋을 추가하여 사용하면 된다.

cxGrid에서 LookupCombo 사용하기

//!!!! use 에 cxDBLookupComboBox 추가
// gridSubFunc 는 그리드의 데이터소스
//MainfuncNoField 는 룩업할 필드

gridSubFunc.DataController.DataSource := dsSubFunc;
MainfuncNoField.PropertiesClass := TcxLookupComboBoxProperties;
with TcxLookupComboBoxProperties(MainfuncNoField.Properties) do
begin
ListSource := dsMainFunc;
ListFieldNames := 'func_name';
KeyFieldNames := 'rno';
end;
MainfuncNoField.DataBinding.FieldName := 'mainfunc_no';

cxGrid뷰에서 필터된 내용만 검색하기

cnt := cxRegion.DataController.FilteredRecordCount;
for I := 0 to cnt - 1 do begin
sFrame := cxRegion.FilterRow.GridView.Columns[2].EditValue;
eFrame := cxRegion.FilterRow.GridView.Columns[3].EditValue;
cxRegion.FilterRow.GridView.DataController.GotoNext;
end;