이것은 http://blog.naver.com/mojirhi/150002732458 모지리님의 블로그를 발췌한 내용입니다.
너무 잘 만드신 것 같습니다. 부럽습니다.
소스:
http://blog.naver.com/mojirhi/150002732458 (모지리님)
argument는 2가지나 3가지를 받도록 했습니다.
//my_excel.of_excel(DW or DS,ib_detailonly,ib_saveobjectinfo)
1.
첫번째는 Excel로 전환할 개체인데 Powerobject로 변경하여
Datawiindowsk datastore 아무거나 입력받을 수 있도록 하였습니다.
두번째는 ib_detailonly로 grid와 closstab에서만 효고가 있으며 true일때는
detail만 grid 형태로 출력하며 숫자형 문자열을 정확히 문자열로 읽어줍니다.
세번째는 ib_saveobjectinfo로 생략가능하며 일반적으로는 사용하지 않습니다.
개발자를 위해서 dw나 ds의 object들의 각종 속성을 excel로 출력해줍니다.
2.ib_detailonly가 false이면 saveasascii를 사용합니다.
ib_detailonly가 True이면 Processing에 따라서
'0'(=form/tabular/group/n-up)과 '2'(=label)은 무조건 SaveAsAscii를 사용하고
'1'(=grid)과 '4'(=closstab)은 of_savedetailonly방식을 사용합니다.
'5'(composite)는 SaveAsAscii방식이 안되므로 모둔 report를 Grid형태로 변경하여 하나의 Excel파일에 Report별로 Sheet를
구분하여 출력합니다.
3. 입력object를 powerobject로 변경하여 관련함수를 공통함수로 재정의하여 사용합니다.
of_describe(),of_modify(),of_getitemstring(),of_getitemnumber(),of_getchild()등입니다.
4.QueryTable관련 부분은 잘 확인해보시기 바라며 column정보는 of_analyze에서 설정합니다.
/* 사용방법 */
my_n_excel my_excel
my_excel = create my_n_excel
my_excel.of_excel(dw_2,false)
/* 엑셀 Userobject*/
/* 아래소스 import 하면 됨*/
$PBExportHeader$my_n_excel.sru
$PBExportComments$Excel 저장 서비스
forward
global type my_n_excel from nonvisualobject
end type
end forward
global type my_n_excel from nonvisualobject
end type
global my_n_excel my_n_excel
type variables
protected:
datastore ids_excel // display값을 임시 저장하기 위한 것.
datastore ids_object // dwo 정보를 정리하기 위한 것
unsignedinteger ii_excelcol = 40 // excel의 열 제한 (255이하)
unsignedinteger ii_excelrow = 65535 // excel의 행 제한 (65535이하)
unsignedinteger ii_titlerow = 1 // header부위의 행 (확장예비용)
unsignedinteger ii_celllen = 255 // excel의 cell값 길이 Max제한
boolean ib_detailonly =True // False는 saveasascii를 사용
// Grid, Crosstab 에서만 효과가 있음.
boolean ib_saveobjectinfo = False // object 정보를 저장할 지
boolean ib_composite = False // Composite인지
//*************************************************************
powerobject ipo_source // Excel로 전환할 개체
object ipo_sourcetype // Datawindow!, Datastore!, Datawindowchild! ,,,
string is_processing // ipo_source의 processing
long il_rowcount // 전환할 row 수
datawindow idw_source // DataWindow용
datastore ids_source // DataStore용
datawindowchild idc_source // DataWindowChild용
datawindowchild idc_report // Composite의 Report용
string is_detail[] // detail밴드의 column, compute 개체이름
string is_objtype[] // is_detail의 objtype
string is_label[] // is_detail의 Label
string is_coltype[] // is_detail의 coltype
long il_objx[] // is_detail의 x좌표
end variables
forward prototypes
public function string of_describe (string as_exp)
public function string of_modify (string as_exp)
public function integer of_string2array (string as_source, string as_separator, ref string as_result[])
public function string of_replaceall (string as_source, string as_before, string as_after)
public function string of_replaceall (string as_source, string as_before, string as_after, boolean ab_matchcase)
public function integer of_analyze ()
public function integer of_saveasascii ()
public function string of_getitemstring (long al_row, string as_colname)
public function string of_getitemnumber (long al_row, string as_colname)
public function integer of_saveinformation ()
public function integer of_savecomposite ()
public function integer of_savedetailonly ()
public function string of_datacopy ()
public function integer of_getchild (string as_report, ref datawindowchild adc_source)
public function long of_writetext (string as_string, string as_filepath)
public function integer of_createdwo (ref datastore ads_source, integer ai_col, boolean ab_header)
public function integer of_excel (powerobject apo_source, boolean ab_detailonly)
public function integer of_excel (powerobject apo_source, boolean ab_detailonly, boolean ab_saveobjectinfo)
end prototypes
public function string of_describe (string as_exp);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_describe
//
// DESCRIPTION : idw_source, ids_source, idc_surce, idc_report에 대하여
// Describe함수를 공용으로 사용할 수 있도록 함.
//
// RETURN : String
// 성공 - as_exp의 결과
// 실패 - '!'
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// as_exp describe()에 전달할 내용
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
if ib_composite then
return idc_report.describe(as_exp)
else
Choose Case ipo_sourcetype
Case DataWindow!
Return idw_source.describe(as_exp)
Case DataStore!
Return ids_source.describe(as_exp)
Case DataWindowChild!
Return idc_source.describe(as_exp)
Case Else
Return "!"
End Choose
end if
end function
public function string of_modify (string as_exp);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_modify
//
// DESCRIPTION : idw_source, ids_source, idc_surce, idc_report에 대하여
// Modify함수를 공용으로 사용할 수 있도록 함.
//
// RETURN : String
// 성공 - as_exp의 결과
// 실패 - '!'
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// as_exp Modify()에 전달할 내용
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
if ib_composite then
return idc_report.modify(as_exp)
else
Choose Case ipo_sourcetype
Case DataWindow!
Return idw_source.modify(as_exp)
Case DataStore!
Return ids_source.modify(as_exp)
Case DataWindowChild!
Return idc_source.modify(as_exp)
Case Else
Return "!"
End Choose
end if
end function
public function integer of_string2array (string as_source, string as_separator, ref string as_result[]);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_string2array
//
// DESCRIPTION : 주어진 문자열을 특정 구분자(예, 탭)로 구분하여
// 배열에 저장하는 함수
//
// RETURN : Integer
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// as_source string soruce_string
// as_separator string separate_charactor
// as_result[] string array result_saved
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi @ gmail . com
///////////////////////////////////////////////////////////////////////////////
string ret[]
integer li_pos, i, li_nextpos, li_len
// Argument 확인
IF len(as_source) = 0 or isnull(as_source) then return -1
IF len(as_separator) = 0 or isnull(as_source) then as_separator = '~t'
IF isnull(as_result) then return -1
as_result = ret //결과배열 초기화
li_len = len(as_separator) - 1
//li_pos = 1
do while(true)
i++
li_pos = li_nextpos + 1
li_nextpos = pos(as_source, as_separator, li_pos)
if li_nextpos > 0 then
if i = 1 then //맨 처음이면
as_result[i] = mid(as_source, li_pos, li_nextpos - li_pos)
else //중간부분
as_result[i] = mid(as_source, li_pos + li_len, li_nextpos - li_pos - li_len)
end if
else //맨 끝이면
as_result[i] = mid(as_source, li_pos + li_len, len(as_source))
exit
end if
loop
return 1
end function
public function string of_replaceall (string as_source, string as_before, string as_after);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_replaceall
//
// DESCRIPTION : 지정된 문자열을 source에서 모두 찾아 바꾸기 함.
// (ib_matchcase를 항상 False로 함.)
//
// RETURN : String
// 바꾸기 된 문자열
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// as_source 전환할 대상 문자열 (~에서)
// as_before 전환전 문자열(~를)
// as_after 전환후 문자열(~으로)
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
return of_replaceall(as_source, as_before, as_after, False)
end function
public function string of_replaceall (string as_source, string as_before, string as_after, boolean ab_matchcase);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_replaceall
//
// DESCRIPTION : 지정된 문자열을 source에서 모두 찾아 바꾸기 함.
//
// RETURN : String
// 바꾸기 된 문자열
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// as_source 전환할 대상 문자열 (~에서)
// as_before 전환전 문자열(~를)
// as_after 전환후 문자열(~으로)
// ab_matchcase 대/소문자 구별(True이면 구별함)
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
long ll_pos
if isnull(ab_matchcase) then ab_matchcase = False
if ab_matchcase then
ll_pos = posW(as_source, as_before)
do while ll_pos > 0
//as_Source = Replace(as_Source, ll_Start, ll_OldLen, as_New)
as_source = replaceW(as_source, ll_pos, len(as_before), as_after)
ll_pos = posW(as_source, as_before)
loop
else
ll_pos = posW(upper(as_source), upper(as_before))
do while ll_pos > 0
as_source = replaceW(as_source, ll_pos, len(as_before), as_after)
ll_pos = posW(upper(as_source), upper(as_before))
loop
end if
return as_source
end function
public function integer of_analyze ();///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_analyze
//
// DESCRIPTION : idw_source, ids_source, idc_source, idc_report에 대하여
// DWObject들의 정보를 수집한다.
// 결과는 is_detail[], is_label[], is_objtype[],
// is_coltype[], il_objx[] 에 남긴다.
//
// RETURN : Integer
// 1 = 성공, -1 = 실패
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// None
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
string ls_objects, ls_object[], ls_labelx[], ls_null[]
string ls_objname, ls_band, ls_type, ls_pos, ls_label, ls_coltype
long i, ll_pos, ll_row, ll_rowcount, ll_null[]
// 결과배열을 초기화 한다.
is_detail = ls_null[]; is_objtype = ls_null
is_label = ls_null[]; is_coltype = ls_null
il_objx = ll_null[]
//-----------------------------------------------------------------------------
// 데이터윈도의 모든 오브젝트를 읽어와서 배열에 담는다.
//-----------------------------------------------------------------------------
ls_objects = of_describe('Datawindow.objects' )
of_string2array(ls_objects, '~t', ls_object)
//-----------------------------------------------------------------------------
// datastore를 이용하여 모든 control의 기본정보를 가져오고
// column의 배열순서를 정하고 Header Text를 가져오도록 한다.
//-----------------------------------------------------------------------------
ids_object.reset()
//개발용 출력을 위해서 Label을 설정함.
ids_object.modify('C1_t.text = "Object_Name"')
ids_object.modify('C2_t.text = "V"')
ids_object.modify('C3_t.text = "Band"')
ids_object.modify('C4_t.text = "Obj_Type"')
ids_object.modify('C5_t.text = "Label"')
ids_object.modify('C6_t.text = "Col_Type"')
ids_object.modify('C7_t.text = "Text"')
ids_object.modify('C8_t.text = "X"')
ids_object.modify('C9_t.text = "Width"')
ids_object.modify('C10_t.text = "X2"')
ids_object.modify('C11_t.text = "Y"')
ids_object.modify('C12_t.text = "Height"')
ids_object.modify('C13_t.text = "Y2"')
ids_object.modify('C14_t.text = "Border"')
ids_object.modify('C15_t.text = "Font.Weight"')
ids_object.modify('C16_t.text = "Color"')
ids_object.modify('C17_t.text = "Bg_Color"')
For i = 1 to upperbound(ls_object)
ls_objname = ls_object[i]
ids_object.InsertRow(0)
ids_object.SetItem(i , 'C1' , ls_objname) // object name
ids_object.SetItem(i , 'C2' , upper(of_describe( ls_objname + '.visible' ))) // True = '1'
ls_band = upper(of_describe( ls_objname + '.band' ))
ids_object.SetItem(i , 'C3' , ls_band) // 'DETAIL', 'HEADER' ,,,
ls_type = upper(of_describe( ls_objname + ".type" ))
ids_object.SetItem(i , 'C4' , ls_type) // 'COLUMN', 'TEXT' ,,,
if ls_type = 'COLUMN' or ls_type = 'COMPUTE' then
ls_label = of_describe(ls_objname + '_t.text')
ids_object.SetItem(i , 'C5' , ls_label) // Label 없으면 '!'
ls_coltype = of_describe(ls_objname + '.coltype')
ids_object.SetItem(i , 'C6' , ls_coltype) // coltype
end if
if ls_type = 'TEXT' then
ids_object.SetItem(i , 'C7' , of_describe( ls_objname + '.text' )) // Label의 내용
end if
ll_pos = integer(of_describe( ls_objname + ".x" ))
//column의 x값이 32766이상은 음수로 나올때의 에러 정정
IF ll_pos < 0 then ll_pos += 65536
ls_pos = right('000000' + string(ll_pos),6)
ids_object.SetItem(i , 'C8' , ls_pos) // X position
ids_object.SetItem(i , 'C9' , of_describe( ls_objname + '.width' )) // 너비
ids_object.SetItem(i , 'C10' , string(ll_pos + long(of_describe( ls_objname + '.width' )))) // X2
ids_object.SetItem(i , 'C11' , right('000000' + (of_describe( ls_objname + ".y" )),6)) // Y Pisition
ids_object.SetItem(i , 'C12' , of_describe( ls_objname + '.height' )) // 높이
ids_object.SetItem(i , 'C13' , string(long(of_describe( ls_objname + ".y" )) + long(of_describe( ls_objname + '.height' )))) // Y2
ids_object.SetItem(i , 'C14' , of_describe( ls_objname + '.border' )) // 테두리
ids_object.SetItem(i , 'C15' , of_describe( ls_objname + '.font.weight' )) // 굵게 보통-400, 굵게 700
ids_object.SetItem(i , 'C16' , of_describe( ls_objname + '.color' )) // 글자색
ids_object.SetItem(i , 'C17' , of_describe( ls_objname + '.background.color' )) // 배경색
Next
//-----------------------------------------------------------------------------
// Header Text가 '_t'로 되어 있지 않은 것을 x좌표로 재확인
// Visible='1', label ='' 것을 모은다.
//-----------------------------------------------------------------------------
ls_object = ls_null //배열 초기화
ids_object.setfilter('C2="1" and C5="!"')
ids_object.filter()
if ids_object.rowcount() > 0 then
for i = 1 to ids_object.rowcount()
ls_object[i] = ids_object.getitemstring(i, 'C1') // object.name
ls_labelx[i] = ids_object.getitemstring(i, 'C8') // object.x
next
end if
ids_object.setfilter('') // filter제거
ids_object.filter()
ids_object.setsort('C9 D') // header중에서 아래쪽에 있는 것을 우선 찾기 위해.
ids_object.sort()
ll_rowcount = ids_object.rowcount()
if upperbound(ls_object) > 0 then
for i = 1 to upperbound(ls_object)
ls_label = ''
ll_row = ids_object.find('C3 > "HEAD" and C4="TEXT" and C8="' + ls_labelx[i] + '"', 1, ll_rowcount)
if ll_row > 0 then
ls_label = ids_object.getitemstring(ll_row, 'C7')
ll_row = ids_object.find('C1="' + ls_object[i] + '"', 1, ll_rowcount)
ids_object.setitem(ll_row, 'C5', ls_label)
end if
next
end if
//-----------------------------------------------------------------------------
// detail밴드에 있는 것을 출력순서로 sort한다.
//-----------------------------------------------------------------------------
ids_object.setfilter('C2="1" and C3="DETAIL" and (C4="COLUMN" or C4="COMPUTE") ')
ids_object.filter()
if is_processing = '2' or is_processing = '4' then
// 출력순서를 'x'좌표를 기준으로 순서대로 출력(왼쪽 순서대로)
ids_object.SetSort('C8 A')
else
// 출력순서를 'y'좌표우선 'x'좌표차선으로 출력(위쪽 왼쪽 순서대로)
ids_object.setSort('C11 A, C8 A')
end if
ids_object.Sort()
for i = 1 to ids_object.rowcount()
is_detail[i] = ids_object.getitemstring(i, 'C1')
is_objtype[i] = ids_object.getitemstring(i, 'C4')
is_label[i] = ids_object.getitemstring(i, 'C5')
is_coltype[i] = ids_object.getitemstring(i, 'C6')
il_objx[i] = long(ids_object.getitemstring(i, 'C8'))
next
return 1
end function
public function integer of_saveasascii ();///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_saveasascii
//
// DESCRIPTION : idw_source, ids_source에 대하여
// SaveAsAscii함수를 사용하여 저장화되 Grid와 Crosstab은
// Excel에서 Column Type에 따라 문자열을 지정해 줌.
// (숫자형 문자열의 Excel전환시 숫자화 되는 것 방지)
//
// RETURN : Integer
// 성공 : 1
// 실패 : -1
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// None
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
integer i, li_rc, li_colDatatype[]
string ls_process, ls_mode, ls_coltype[]
string ls_filepath = 'C:\Excel.txt', ls_filename = 'excel'
OleObject MyExcel, MyQuery
/*
li_rc = GetFileSaveName ( "Select File", ls_filepath, ls_filename, "TXT", &
"Text Files (*.txt),*.txt") //, "C:\", 32770)
If li_rc <> 1 then Return li_rc //0 파일 저장 취소, -1 Error
IF FileExists(ls_filepath) Then
li_rc = Messagebox ("저장확인", ls_filepath + "'~r~n 위 파일이 이미 있습니다.~r~n" + &
"기존 파일을 바꾸시겠습니까?", Question!, YesNo!, 2)
IF li_rc = 2 Then Return 0 // 파일 저장 취소
End If
*/
if ib_detailonly then //'1','4'
li_rc = ids_excel.saveasascii(ls_filepath)
if li_rc <> 1 then &
MessageBox('1,4', 'SaveAsAscii로 변환중 오류가 발생했습니다.', stopsign!)
else // False or '0', '2'
choose case ipo_sourcetype
case datawindow!
li_rc = idw_source.saveasascii(ls_filepath)
case datastore!
li_rc = ids_source.saveasascii(ls_filepath)
case datawindowchild!
messagebox('잠깐!', '이 객체는 SaveAsAscii를 지원하지 않습니다.~r~n' &
+ 'grid형태로 출력을 변경합니다.', exclamation!)
ib_detailonly = true
return of_excel(idc_source, ib_detailonly)
case else
messagebox('Error', 'of_saveasascii() ~r~n 알수없는 오류가 발생했습니다.', stopsign!)
return -1
end choose
end if
if li_rc <> 1 then
MessageBox('오류!', 'SaveAsAscii로 변환중 오류가 발생했습니다.', stopsign!)
return -1
end if
MyExcel = Create OleObject
li_rc = MyExcel.ConnectToNewObject("excel.application")
IF li_rc <> 0 THEN
MessageBox("Information!", "File Conversion Failed!")
MessageBox('오류!', 'Excel을 구동하면서 오류가 발생했습니다.', stopsign!)
Destroy MyExcel
RETURN -1
end if
MyExcel.WorkBooks.Add()
MyExcel.ActiveWorkbook.Sheets.Add.Name = ls_filename
MyQuery = MyExcel.ActiveWorkbook.Sheets(1).QueryTables.Add('TEXT;' + ls_filepath , MyExcel.ActiveWorkbook.Sheets(1).Cells(1,1) )
if ib_detailonly then
// Column Type을 확인한다.
for i = 1 to upperbound(is_coltype)
IF left(upper(is_coltype[i]), 4) = 'CHAR' then
li_coldatatype[i] = 2
else
li_coldatatype[i] = 1
end if
next
MyQuery.TextFileColumnDataTypes = li_coldatatype
end if
MyQuery.refresh()
MyExcel.ActiveWorkbook.sheets(1).Columns.AutoFit
MyExcel.ActiveWorkbook.sheets(1).Cells(1,1).select
MyExcel.Application.Visible = True
MyExcel.DisconnectObject()
if ib_saveobjectinfo then of_saveinformation()
Return 1
end function
public function string of_getitemstring (long al_row, string as_colname);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_getitemstring
//
// DESCRIPTION : idw_source, ids_source, idc_surce, idc_report에 대하여
// getitemstring함수를 공용으로 사용할 수 있도록 함.
//
// RETURN : String
// 성공 - 결과문자열
// 실패 - '!'
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// al_row row 번호
// as_colname column 이름
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
Choose Case ipo_sourcetype
Case DataWindow!
Return idw_source.getitemstring(al_row, as_colname)
Case DataStore!
Return ids_source.getitemstring(al_row, as_colname)
Case DataWindowChild!
Return idc_source.describe( 'Evaluate(as_colname), al_row)' )
Case Else
Return "!"
End Choose
end function
public function string of_getitemnumber (long al_row, string as_colname);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_getitemnumber
//
// DESCRIPTION : idw_source, ids_source, idc_surce, idc_report에 대하여
// getitemnumber함수를 공용으로 사용할 수 있도록 함.
//
// RETURN : String (number가 아님에 주의할 것)
// 성공 - 결과문자열
// 실패 - '!'
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// al_row row 번호
// as_colname column 이름
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
Choose Case ipo_sourcetype
Case DataWindow!
Return string(idw_source.getitemnumber(al_row, as_colname))
Case DataStore!
Return string(ids_source.getitemnumber(al_row, as_colname))
Case DataWindowChild!
Return idc_source.describe( 'Evaluate(as_colname), al_row)' )
Case Else
Return "!"
End Choose
end function
public function integer of_saveinformation ();///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_saveinformation
//
// DESCRIPTION : Excel로 전환한 개체의 DWObject들의 정보를 출력함.
// (개발시의 column자료를 확인하기 위함)
//
// RETURN : Integer
// 성공 : 1
// 실패 : -1
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// None
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
integer i, li_rc, li_colDatatype[]
string ls_process, ls_mode, ls_coltype[]
string ls_filepath, ls_filename
OleObject MyExcel
OleObject MyQuery
li_rc = GetFileSaveName ( "오브젝트 정보 저장", ls_filepath, ls_filename, "TXT", &
"Text Files (*.txt),*.txt") //, "C:\", 32770)
If li_rc <> 1 then Return li_rc //0 파일 저장 취소, -1 Error
IF FileExists(ls_filepath) Then
li_rc = Messagebox ("저장확인", ls_filepath + "'~r~n 위 파일이 이미 있습니다.~r~n" + &
"기존 파일을 바꾸시겠습니까?", Question!, YesNo!, 2)
IF li_rc = 2 Then Return 0 // 파일 저장 취소
End If
ids_object.setfilter('')
ids_object.filter()
li_rc = ids_object.saveasascii(ls_filepath)
if li_rc <> 1 then
MessageBox('오류!', 'SaveAsAscii로 변환중 오류가 발생했습니다.', stopsign!)
return -1
end if
MyExcel = Create OleObject
li_rc = MyExcel.ConnectToNewObject("excel.application")
IF li_rc <> 0 THEN
MessageBox('오류!', 'Excel을 구동하면서 오류가 발생했습니다.', stopsign!)
Destroy MyExcel
RETURN -1
end if
MyExcel.WorkBooks.Open(ls_filepath)
MyExcel.ActiveWorkbook.sheets(1).Cells(1,1).select
MyExcel.Application.Visible = True
MyExcel.DisconnectObject()
Return 1
end function
public function integer of_savecomposite ();///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_savecomposite
//
// DESCRIPTION : idw_source, ids_source에 대하여 composite형태를
// Report 단위로 처리하여 Excel의 sheet로 변환해 줌.
// DataWindowChild는 saveasascii방식이 적용안된므로
// Grid형태로 변형하여 출력함.
//
// RETURN : Integer
// 성공 : 1
// 실패 : -1
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// None
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
Integer i, j, li_rpt, li_rc, li_dwc, li_cnt, li_coldatatype[]
String ls_copydata, ls_objects, ls_object[], ls_type
string ls_rc, ls_report[], ls_process, ls_filepath='C:\excel.txt'
OleObject MyExcel, MyQuery
// datawindow의 모든 dwobject를 읽어와 ls_object[]에 저장
ls_objects = of_describe('Datawindow.objects')
of_string2array(ls_objects, '~t', ls_object[])
// report만 ls_report[]에 저장
for i = 1 to upperbound(ls_object[])
ls_type = of_describe( ls_object[i] + ".type" )
choose case ls_type
case 'report'
li_rpt++
ls_report[li_rpt] = ls_object[i]
case else
// report가 아닌것은 제외
end choose
next
//-----------------------------------------------------------------------------
// Report개체는 시트를 구분하여 처리한다.
//-----------------------------------------------------------------------------
TRY
myExcel = CREATE oleobject
li_rc = myExcel.ConnectToNewObject ( "Excel.Application" )
IF li_rc <> 0 THEN
MessageBox ( "Error", String ( li_rc ) )
Return -1
END IF
myExcel.Application.Visible = False
myExcel.Workbooks.Add()
ib_composite = true // 여기서부터 공용함수를 idc_report로 바꾼다.
if upperbound(ls_report) > 0 then
messagebox('참고', '선택하신 개체는 Excel로 전환시 ~r~n' &
+ '부득이하게 형태가 변경됩니다.', Information!)
for i = 1 to upperbound(ls_report)
li_rc = of_getchild(ls_report[i], idc_report)
if li_rc <> 1 then
messagebox('잠깐!', 'getchild 실패', Stopsign!)
return -1
end if
il_rowcount = idc_report.rowcount()
ls_process = of_describe('Datawindow.Processing')
choose case ls_process
case '0', '1', '2', '4'
// 무조건 Grid형태로 진행함.
case else
continue
end choose
li_rc = of_analyze()
if li_rc <> 1 then
messagebox('잠깐!', 'report분석 실패', Stopsign!)
return -1
end if
li_rc = of_createdwo(ids_excel, upperbound(is_detail), False)
if li_rc <> 1 then
messagebox('잠깐!', 'report용 datastore작성 실패', Stopsign!)
return -1
end if
ls_copydata = of_datacopy()
if ls_copydata = '!' then
messagebox('잠깐!', 'report용 datacopy실패:'+ls_copydata, Stopsign!)
continue
end if
for j = 1 to upperbound(is_coltype)
IF left(upper(is_coltype[j]), 4) = 'CHAR' then
li_coldatatype[j] = 2
else
li_coldatatype[j] = 1
end if
next
li_cnt++
of_writetext(ls_copydata, ls_filepath)
ClipBoard ( ls_copydata ) //복사
myExcel.ActiveWorkbook.Sheets.add.name = ls_report[i]
MyQuery = MyExcel.ActiveWorkbook.Sheets(ls_report[i]).QueryTables.Add &
('TEXT;' + ls_filepath , MyExcel.ActiveWorkbook.Sheets(ls_report[i]).Cells(1,1) )
MyQuery.TextFileColumnDataTypes = li_coldatatype
MyQuery.refresh
myExcel.ActiveWorkbook.sheets(ls_report[i]).Cells(1,1).select
myExcel.ActiveWorkbook.sheets(ls_report[i]).Columns.AutoFit
if ib_saveobjectinfo then of_saveinformation()
next
//한개도 성공하지 못한 경우에는 에러를 반환함.
if li_cnt < 1 then return -1
else
messagebox('잠깐!', '작업할 Report가 하나도 없습니다.', Stopsign!)
return -1
end if
CATCH ( exception e )
MessageBox ( "Error", e.GetMessage() )
FINALLY
if isvalid(myExcel) then
myExcel.Application.Visible = True
myExcel.DisconnectObject()
DESTROY myExcel
end if
END TRY
RETURN 1
return 1
end function
public function integer of_savedetailonly ();///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_savedetailonly
//
// DESCRIPTION : idw_source, ids_source에 대하여
// SaveAsAscii를 적용하지않고 Detail만 Grid형태로 출력함.
// 문자열에 대햐여 숫자로 전환된지 않도록 방지하고,
// SaveAsAscii에서 잘못되는 group소계 부분을 삭제함.
// (Excel에서 부분합 같은 기능으로 간단히 할 수 있으며
// Excel로 전환후 Data의 재사용성을 제고함.)
//
// RETURN : Integer
// 성공 : 1
// 실패 : -1
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// None
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
integer li_rc
string ls_rc
if is_processing = '4' then
// Crosstab은 StaticMode를 설정함.
ls_rc = of_modify('DataWindow.crosstab.StaticMode = "yes"')
if ls_rc = '!' or ls_rc = '?' then
messagebox ('오류', 'of_modify() ~r~n Crosstab의 StaticMode를 설정하지 못했습니다.', Stopsign!)
return -1
end if
end if
li_rc = of_analyze() // objects를 분석.
if li_rc <> 1 then
messagebox ('오류', 'of_analyze() ~r~n Datawindow를 분석하는 중에 오류가 발생했습니다.', Stopsign!)
return -1
end if
li_rc = of_createdwo(ids_excel, upperbound(is_detail), False) // 복사용 DataStore 준비.
if li_rc <> 1 then
messagebox ('오류', 'of_createdwo ~r~n 복사용 DataStore를 만들지 못했습니다.', Stopsign!)
return -1
end if
ls_rc = of_datacopy() // 자료를 ids_excel로 복사.
if ls_rc = '!' then
messagebox ('오류', 'of_displaycopy() ~r~n Data를 복사하지 못했습니다.', Stopsign!)
return -1
end if
return of_saveasascii() // Excel로 읽기
end function
public function string of_datacopy ();///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_datacopy
//
// DESCRIPTION : Datawindow를 Display된 내용으로 임시 DataStore로 Copy한다.
// Detail Band와 그 Title만 전환함. 서식적용없는 내용Copy임.
//
// RETURN : String
// 성공 - Tab으로 분리된 문자열
// 실피 - '!'
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// None
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
string ls_exp, ls_data, ls_editstyle, ls_copydata
Long i, j, ll_rowcount
Integer li_colcount
//-----------------------------------------------------------------------------
// row , column의 개수를 가져온다.
// row의 갯수는 Excel의 한계인 65536에서 Title열을 뺀 65535로 제한한다.
//-----------------------------------------------------------------------------
li_colcount = upperbound(is_detail)
ll_rowcount = il_rowcount
IF ll_rowcount < 1 then return '!' //처리할 행이 없음.
IF li_colcount < 1 then return '!' //처리할 열이 없음.
IF li_colcount > ii_excelcol then li_colcount = ii_excelcol
IF ll_rowcount > ii_excelrow then ll_rowcount = ii_excelrow
//-----------------------------------------------------------------------------
// Data복사용 DataStore를 설정한다.
//-----------------------------------------------------------------------------
ids_excel.reset()
FOR i = 1 TO ll_rowcount // row의 수만큼 DataStore에 추가한다.
ids_excel.InsertRow(0)
NEXT
//-----------------------------------------------------------------------------
// 자료를 copy한다.
// data에 탭, 개행문자 등이 있을 경우에는 copy & paste에 문제가 되므로 공백대체.
// 계산필드에 혹시 따옴표가 있을 경우에는 Evaluate의 따옴표 종류를 다르게 할 것.
//-----------------------------------------------------------------------------
FOR j = 1 to li_colcount
ls_data = ''
ls_editstyle = of_describe(is_detail[j] + ".edit.style")
// 원Data의 coltype을 보고 char(##), number에 따라 처리
choose case ls_editstyle
case 'checkbox'
if left(is_coltype[j],4) = 'CHAR' then //문자열인 경우
for i = 1 to ll_rowcount
ls_data = of_getitemstring(i, is_detail[j])
// 0으로 시작하는 숫자형 문자열의 변형 방지 예) 0001 -> 1 대안 '0001
if asc(ls_data) = 48 then ls_data = "'" + ls_data
ids_excel.SetItem(i , j , ls_data)
next
else //숫자형인 경우
for i = 1 to ll_rowcount
ls_data = of_getitemnumber(I,is_detail[j])
ids_excel.SetItem(i , j , ls_data)
next
end if
case else //checkbox 이외의 edit style
IF is_objtype[j] = 'COLUMN' then
FOR i = 1 TO ll_rowcount
ls_data = of_Describe("Evaluate('LookupDisplay(" + &
is_detail[j] + ")' , " + String(i) + ")")
if isnull(ls_data) then ls_data = ''
// 탭과 개행문자를 공백으로 대치
of_replaceall(ls_data, char(9) , ' ') //Tab
of_replaceall(ls_data, char(10), ' ') //LF
of_replaceall(ls_data, char(13), ' ') //CR
of_replaceall(ls_data, char(34), char(39)) //쌍따옴표
// 0으로 시작하는 숫자형 문자열의 변형 방지 예) 0001 -> 1 대안 '0001
//if upper(adw_source.describe( ls_detail[j] + ".coltype" )) = 'CHAR' then
// if asc(ls_data) = 48 then ls_data = "'" + ls_data
//end if
ids_excel.SetItem(i , j , ls_data)
NEXT
//계산필드 내용 확인
elseif is_objtype[j] = 'COMPUTE' then
ls_exp = of_describe(is_detail[j] + ".expression")
FOR i = 1 TO ll_rowcount
ls_data = of_Describe("Evaluate('" + ls_exp + "'," + string(i) + ")")
if isnull(ls_data) then ls_data = ''
// 탭과 개행문자를 공백으로 대치
of_replaceall(ls_data, char(9) , ' ') //Tab
of_replaceall(ls_data, char(10), ' ') //LF
of_replaceall(ls_data, char(13), ' ') //CR
of_replaceall(ls_data, char(34), char(39)) //쌍따옴표
// 0으로 시작하는 숫자형 문자열의 변형 방지 예) 0001 -> 1 대안 '0001
//if upper(adw_source.describe( ls_detail[j] + ".coltype" )) = 'CHAR' then
// if asc(ls_data) = 48 then ls_data = "'" + ls_data
//end if
ids_excel.SetItem(i , j , ls_data)
NEXT
end if
end choose //edit style에 따른 처리 종료
NEXT
//-----------------------------------------------------------------------------
// Header title 삽입
//-----------------------------------------------------------------------------
ids_excel.InsertRow(1)
for i = 1 to upperbound(is_label)
ids_excel.SetItem(1 , i , is_label[i])
next
ls_copydata = ids_excel.object.datawindow.data
RETURN ls_copydata
end function
public function integer of_getchild (string as_report, ref datawindowchild adc_source);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_getchild
//
// DESCRIPTION : idw_source, ids_source에 대하여
// getchild함수를 공용으로 사용할 수 있도록 함.
//
// RETURN : String
// 성공 : 1
// 실패 : -1
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// as_report getchild에 사용할 report명
// adc_source getchild로 할당될 DataWindowChild 참조개체
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
Choose Case ipo_sourcetype
Case DataWindow!
Return idw_source.getchild(as_report, adc_source)
Case DataStore!
Return ids_source.getchild(as_report, adc_source)
Case DataWindowChild!
Return -1 // idc_source.getchild(as_report, adc_source)
Case Else
Return -1
End Choose
end function
public function long of_writetext (string as_string, string as_filepath);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_writetext
//
// DESCRIPTION : 주어진 문자열을 Text파일로 출력함.
//
// RETURN : Long (출력된 문자열 길이)
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// as_string 파일로 쓸 문자열
// as_filepath 저장할 파일명을 포함한 Path
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi @ gmail . com
///////////////////////////////////////////////////////////////////////////////
long i, ll_len, ll_loop, ll_FileNo, ll_pos
string ls_temp
ll_len = len(as_string)
ll_loop = integer(ll_len/32765) + 1
ll_FileNo = FileOpen(as_filepath, StreamMode!, Write!, LockWrite!, Replace!)
ll_pos = 1
For i = 1 To ll_loop
ls_temp = Mid(as_string, ll_pos, 32765)
ll_pos += 32765
If FileWrite(ll_FileNo, ls_temp) = -1 Then
Return -1
End if
Next
FileClose(ll_FileNo)
return ll_len
end function
public function integer of_createdwo (ref datastore ads_source, integer ai_col, boolean ab_header);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_createdwo
//
// DESCRIPTION : 임시로 사용할 datastore의 dwobject를 만든다.
//
// RETURN : Integer
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// ads_source source datastore
// ai_col dwobject의 열수를 지정.
// ab_header Header름 만드는지의 옵션
// True 만듦 - DwObject용
// False 만들지 않음 - DataCopy용
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
string ls_syntax
integer i
if not isvalid(ads_source) or isnull(ads_source) then return -1
if ai_col > 255 then ai_col = 255
ls_syntax = ls_syntax + 'release 9;'
ls_syntax = ls_syntax + '~r~n' + 'datawindow(units=0 timer_interval=0 color=16777215 processing=1 HTMLDW=no print.printername="" print.documentname="" print.orientation = 0 print.margin.left = 110 print.margin.right = 110 print.margin.top = 96 print.margin.bottom = 96 print.paper.source = 0 print.paper.size = 0 print.canusedefaultprinter=yes print.prompt=no print.buttons=no print.preview.buttons=no print.cliptext=no print.overrideprintjob=no print.collate=yes hidegrayline=no grid.lines=0 )'
ls_syntax = ls_syntax + '~r~n' + 'header(height=80 color="536870912" )'
ls_syntax = ls_syntax + '~r~n' + 'summary(height=0 color="536870912" )'
ls_syntax = ls_syntax + '~r~n' + 'footer(height=0 color="536870912" )'
ls_syntax = ls_syntax + '~r~n' + 'detail(height=92 color="536870912" )'
ls_syntax = ls_syntax + '~r~n' + 'table('
for i = 1 to ai_col
ls_syntax = ls_syntax + '~r~n' + 'column=(type=char('+ string(ii_celllen) + ') updatewhereclause=yes name=C' + string(i) + ' dbname="C' + string(i) +'" )'
next
ls_syntax = ls_syntax + '~r~n' + ' )'
if ab_header then
for i = 1 to ai_col
ls_syntax = ls_syntax + '~r~n' + 'text(band=header alignment="2" text="C' + string(i) + '" border="0" color="0" x="' + string(i*100 + 9) + '" y="8" height="64" width="91" html.valueishtml="0" name=C' + string(i) + '_t visible="1" font.face="Arial" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" )'
next
end if
for i = 1 to ai_col
ls_syntax = ls_syntax + '~r~n' + 'column(band=detail id='+ string(i) +' alignment="0" tabsequence=' + string(i*10) + ' border="0" color="0" x="'+ string(i*100 + 9) +' " y="8" height="76" width="91" format="[general]" html.valueishtml="0" name=C' +string(i) + ' visible="1" edit.limit=0 edit.case=any edit.focusrectangle=no edit.autoselect=yes edit.autohscroll=yes edit.imemode=0 font.face="Arial" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" )'
next
ls_syntax = ls_syntax + '~r~n' + 'htmltable(border="1" )'
ls_syntax = ls_syntax + '~r~n' + 'htmlgen(clientevents="1" clientvalidation="1" clientcomputedfields="1" clientformatting="0" clientscriptable="0" generatejavascript="1" encodeselflinkargs="1" netscapelayers="0" )'
ls_syntax = ls_syntax + '~r~n' + 'export.xml(headgroups="1" includewhitespace="0" metadatatype=0 savemetadata=0 )'
ls_syntax = ls_syntax + '~r~n' + 'import.xml()'
ls_syntax = ls_syntax + '~r~n' + 'export.pdf(method=0 distill.custompostscript="0" xslfop.print="0" )'
return ads_source.create(ls_syntax)
end function
public function integer of_excel (powerobject apo_source, boolean ab_detailonly);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_excel
//
// DESCRIPTION : Datawindow와 DataStrore를 Excel로 전환함.
//
// RETURN : Integer
// 1 = 성공, -1 = 실패
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// apo_source Excel로 전환할 Object
// ab_detailonly Detail만 grid로 전환할 옵션
// Grid 및 Crosstab에서만 유효하며
// Composite는 무조건 True임
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
integer li_rc
string ls_rc, ls_mode
powerobject lpo_source
if isnull(ib_detailonly) then return -1
ib_detailonly = ab_detailonly
lpo_source = apo_source
if not(isnull(lpo_source)) and isvalid(lpo_source) then
ipo_sourcetype = lpo_source.typeof()
choose case ipo_sourcetype
case datawindow!
idw_source = lpo_source
il_rowcount = idw_source.rowcount()
case datastore!
ids_source = lpo_source
il_rowcount = ids_source.rowcount()
case datawindowchild!
idc_source = lpo_source
il_rowcount = idc_source.rowcount()
case else
return -1
end choose
is_processing = of_describe('Datawindow.Processing')
ls_rc = of_describe('Datawindow.data')
if trim(ls_rc) = '' and is_processing <> '5' then
messagebox('잠깐!', 'Data가 없습니다.', stopsign!)
return -1
end if
else
messagebox('잠깐!', '작업할 수 없는 상태입니다.', stopsign!)
return -1
end if
choose case is_processing
case '0', '2' // Form/Tabular/N-Up, Label은 무조건 saveasascii를 적용함.
ib_detailonly = False
li_rc = of_saveasascii()
case '1', '4' // Grid, Crosstab은 ib_detailonly에 따름.
if ib_detailonly then
li_rc = of_savedetailonly()
else
li_rc = of_saveasascii()
end if
case '5' // Composite는 SaveAsAscii가 안됨
ib_detailonly = True
li_rc = of_savecomposite()
case else
messagebox('잠깐!', '지원하지 않은 형식의 Data입니다.', Stopsign!)
end choose
if li_rc <> 1 then
messagebox('잠깐!', 'Excel로 전환되지 못했습니다.', Stopsign!)
end if
return 1
end function
public function integer of_excel (powerobject apo_source, boolean ab_detailonly, boolean ab_saveobjectinfo);///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : of_excel(개발용)
//
// DESCRIPTION : Datawindow와 DataStrore를 Excel로 전환함.
// 추가로 전환된 후에 DWObject정보를 Excel로 출력함.
// (Composite는 맨 마지막 Report만 나옴.)
//
// RETURN : Integer
// 1 = 성공, -1 = 실패
//
// ARGUMENTS DESCRIPTION
// ------------------------------------------------------------------------
// apo_source Excel로 전환할 Object
// ab_detailonly Detail만 grid로 전환할 옵션
// Grid 및 Crosstab에서만 유효하며
// Composite는 무조건 True임
// ab_saveobjectinfo 개발용으로 DWObject를 출력할 것인지 옵션
//
///////////////////////////////////////////////////////////////////////////////
// mojirhi (mojirhi @ gmail . com)
///////////////////////////////////////////////////////////////////////////////
integer li_rc
if isnull( ab_saveobjectinfo ) then return -1
li_rc = messagebox('DWObject정보저장', &
'DWObject정보를 저장하시겠습니까?', &
Question!, YesNo!, 1)
if li_rc = 1 then
ib_saveobjectinfo = ab_saveobjectinfo
end if
return of_excel(apo_source, ab_detailonly)
end function
event constructor;ids_object = create datastore
ids_excel = create datastore
of_createdwo(ids_object, 30, True)
end event
on my_n_excel.create
call super::create
TriggerEvent( this, "constructor" )
end on
on my_n_excel.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on
event destructor;if isvalid(ids_excel) then destroy ids_excel
if isvalid(ids_object) then destroy ids_object
end event