Menu

[9e32fb]: / ExcelObjects_.exw  Maximize  Restore  History

Download this file

190 lines (154 with data), 6.0 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
without warning
-- This demo is converted from the Object Oriented Euphoria version using its
-- preprocessor feature (plus a couple of minor edits). This demo will run under
-- Euphoria 2.4 or greater, however, it is recommended that it be run under v2.5.
-- If v2.4 is used, and the program crashes, Excel will not be properly closed.
-- You will need to kill the process from the Task Manager. Under v2.5, the
-- crash routine will ensure that Euphoria releases it's reference count on Excel.
include win32lib.ew
include eucom.ew
include excel9.ew
include comclass_.ew
with trace
include ExcelObjects_.ew
procedure com_error_handler( atom err, sequence msg )
integer ok
if not is_error( err ) then
return
end if
ok = message_box( sprintf("Error %d: %s", {err, msg}), "COM Error", MB_ICONERROR )
end procedure
object void, bstr
-- Create the window using win32lib
constant
Win = create( Window, "Excel Demo", 0, 200, 200, 160, 250, 0 ),
TextEdit = create( MleText, "<enter text here>", Win, 10, 30, 120, 60, 0 ),
ColLable = create( LText, "Row #", Win, 10, 95, 50, 20, 0 ),
RowLable = create( LText, "Col #", Win, 70, 95, 50, 20, 0 ),
RowEdit = create( EditText, "1", Win, 10, 115, 50, 30, ES_NUMERIC ),
ColEdit = create( EditText, "1", Win, 70, 115, 50, 30, ES_NUMERIC ),
DoIt = create( PushButton, "Update", Win, 10, 150, 120, 30, 0 ),
GetIt = create( PushButton, "Get", Win, 10, 190, 120, 30, 0 )
-- use these for our objects...
object App
object ws
object wbs
object wb
object wss
object ok
-- Start up Excel. It will be invisible to start, so we need to make it visible. If you don't
-- do this, and do not call Application.Quit before the program ends, you'll end up with an invisible
-- Excel running in the background, and will need to kill it using TaskManager.
App = active_ActiveX_i( 0, Application_clsid_ix )
if not App then
App = create_com_object( Application_clsid_ix )
end if
Visible_ExcelApplication_i( App, -1 )
function rc_to_cell( integer row, integer col )
sequence cell
cell = ""
if col > 26 then
cell &= floor( col / 26 ) + 'A' - 1
end if
cell &= (remainder( col, 26 ) + 'A' - 1) & sprint(row)
return cell
end function
procedure do_it(atom id, atom msg, sequence params)
object array
object bstr
sequence cell, text, str
object range
integer col, base
-- get the cell row and column numbers, and format into a string
cell = "A1:" & rc_to_cell(getNumber( RowEdit ), getNumber( ColEdit ) )
range = range_WorkSheet_s( ws, cell )
if is_error( range ) then
return
end if
range = indirect_COM_( range)
text = getText( TextEdit )
text = repeat( repeat( text, getNumber( ColEdit ) ), getNumber( RowEdit ) )
for i = 1 to length(text) do
for j = 1 to length(text[1]) do
text[i][j] = alloc_Bstr_( text[i][j] )
end for
end for
array = create_SafeArray_i( text, VT_BSTR )
-- get the text to put in and set the value for the range
Value_Range_aa( range, array, VT_VARIANT + VT_ARRAY )
-- free the range and array and avoid memory leaks
void = release_COM_( range)
com_error(destroy_safearray( array ))
end procedure
setHandler( DoIt, w32HClick, routine_id("do_it"))
procedure get_it(atom id, atom msg, sequence params)
atom array, row, col
object range
sequence cell1, cell2, text
object val
-- get the cell row and column numbers, and format into a string
row = getNumber( RowEdit )
col = getNumber( ColEdit )
cell1 = "A1"
cell2 = rc_to_cell( row, col )
-- get a range object for that cell--Excel seems to want named variables
range = indirect_COM_( range_WorkSheet_ss( ws, cell1, cell2 ) )
-- get the array of values
val = Value_Range_( range)
if atom(val) then
val = {{val}}
end if
text = ""
for i = 1 to length(val) do
if sequence( val[i] ) then
for j = 1 to length(val[i]) do
if atom(val[i][j]) then
val[i][j] = sprint(val[i][j])
end if
text &= val[i][j] & 32
end for
text &= "\r\n"
else
text &= val[i] & "\r\n"
end if
end for
setText( TextEdit, text )
end procedure
setHandler( GetIt, w32HClick, routine_id("get_it"))
integer change_flag
change_flag = 0
procedure AppEvents_SheetChange_proc( atom this, atom Sh, atom Target )
-- gets sent twice, for some reason...
if change_flag then
void = message_box( "Successfully changed!","SheetChange",0)
end if
change_flag = 1 - change_flag
end procedure
--com_event_routine( App, AppEvents_SheetChange, routine_id("AppEvents_SheetChange_proc"))
procedure close_win( atom id, atom msg, sequence params)
-- close Excel and cleanup COM stuff before we exit
Saved_Workbook_i( wb, -1 )
quit_ExcelApplication_( App)
end procedure
setHandler( Win, w32HClose, routine_id("close_win"))
-- We ultimately want to get at a Worksheet, but need to first get the Workbooks collection, then
-- create a Workbook, then get its Worksheets collection, then get the specific Worksheet (see Excel
-- documentation for the specifics on the object model).
-- Note that I use ref_com_object here, since App passes back pointers to the objects. By doing this,
-- EuCOM will take care of certain housekeeping issues for me, and it's simpler to call invoke().
wbs = Workbooks_ExcelApplication_( App)
wb = Add_Workbooks_( wbs)
wss = Worksheets_Workbook_( wb)
ws = Item_Worksheets_o( wss, 1)
function excel_crash( object o )
quit_ExcelApplication_( App)
release_com()
puts(2, "The demo crashed...\n")
return 0
end function
if routine_id("crash_routine") != -1 then
call_proc( routine_id("crash_routine"), {routine_id("excel_crash")})
end if
com_err_out( - routine_id("com_error_handler"))
WinMain( Win, Normal )
release_com()
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.