/* RxXL_Automation_016.rex */ parse source src d_title = substr(src,src~lastpos('\')+1,src~length-src~lastpos('\')) /* The purpose of this demonstration is to show how to "copy & paste" from one worksheet to another. It's not quite as simple as it sounds. :-) */ slowdown = .true --Clear the screen call SysCls --Using the WinSystm.cls (see ::requires below), lets create a Windows Clipboard object clipboard = .WindowsClipboard~new --Now lets empty whatever might be currently on the clipboard clipboard~Empty --And copy our own string of data to the clipboard clipboard~Copy("This Came From The Windows ClipBoard - Not Sheet1") -- Create the Excel object if slowdown then do smsg = .infoDlg~new(d_title,'Create The Excel Object') smsg~Execute('ShowTop') end xlobj = .OleObject~New('Excel.Application') /*Turn the visible attribute on so that we can see what is happening In a production application, this can be set to false */ xlobj~Visible = .true --Create a new workbook with 1 worksheet if slowdown then do smsg = .infoDlg~new(d_title,'Create a workbook with 2 worksheets') smsg~Execute('ShowTop') end xlobj~Application~SheetsInNewWorkBook = 2 xlobj~WorkBooks~Add --Select Sheet1 and put a value in 2 cells if slowdown then do smsg = .infoDlg~new(d_title,'Put values in A1 and A2') smsg~Execute('ShowTop') end xlobj~Sheets('Sheet1')~Select xlobj~Cells(1,'A')~Value = 10 xlobj~Cells(2,'A')~Value = 20 --Use the Excel "Copy" method to capture the contents of cell A1 if slowdown then do smsg = .infoDlg~new(d_title,'Copy the contents of A1 (or at least try to)') smsg~Execute('ShowTop') end xlobj~Range('A1')~Copy --Now select cell A1 of Sheet2 and paste the data if slowdown then do smsg = .infoDlg~new(d_title,'Select Sheet2') smsg~Execute('ShowTop') end xlobj~Sheets('Sheet2')~Select if slowdown then do smsg = .infoDlg~new(d_title,'Select Cell A1') smsg~Execute('ShowTop') end xlobj~Range('A1')~Select if slowdown then do smsg = .infoDlg~new(d_title,'Paste value in A1') smsg~Execute('ShowTop') end xlobj~ActiveSheet~Paste if slowdown then do smsg = .infoDlg~new(d_title,'* * *> S U R P R I S E <* * *') smsg~Execute('ShowTop') end /* SURPRISE What we wanted to be in cell A1 of Sheet2 (the value of A1 in Sheet1) isn't what we got. What was pasted was the contents of the Windows Clipboard. WHY When using OleObject our class heirarchy is that the OleObject class is a subclass of the Object Class and inherits all the methods of the Object Class. In the case of the "Paste" method, the OleObject class determines that he doesn't have such a method NOR has it inherited such a method from the Object Class; therefore, it sends the Paste to its UNKNOWN method, which is the basis for how ActiveX/OLE works. In the case of the "Copy" method, the OleObject class determines that he doesn't have such a method BUT it has inherited a Copy method from the Object Class, so the method gets executed by the Object Class. And basically what we did in the line xlobj~Range('A1')~Copy was to make a copy of xlobj~Range('A1'), but we didn't do anything with it. In our case, in order to be certain that the Copy method gets sent to xlobj vs. OleObject we must send the "Copy" method directly to the Unknown method. */ /* Lets go back to Sheet1 and get the contents of cell A2, but this time we'll pass the Copy method directly to the Unknown method. When we send a method directly to Unknown we must supply 2 arguments 1) the method name 2) any arguments the method requires (in our case none) */ --Select Sheet1 if slowdown then do smsg = .infoDlg~new(d_title,'Lets try that again') smsg~Execute('ShowTop') end if slowdown then do smsg = .infoDlg~new(d_title,'Select Sheet1') smsg~Execute('ShowTop') end xlobj~Sheets('Sheet1')~Select --Copy the contents of A2 by passing Copy to Unknown if slowdown then do smsg = .infoDlg~new(d_title,'Use the Unknown method to copy A2') smsg~Execute('ShowTop') end xlobj~Range('A2')~Unknown('Copy',.nil) --Select Sheet2 if slowdown then do smsg = .infoDlg~new(d_title,'Select Sheet2') smsg~Execute('ShowTop') end xlobj~Sheets('Sheet2')~Select --Place our cursor where we want to paste the information if slowdown then do smsg = .infoDlg~new(d_title,'Select cell A2') smsg~Execute('ShowTop') end xlobj~Range('A2')~Select --Paste the data if slowdown then do smsg = .infoDlg~new(d_title,'Paste the data') smsg~Execute('ShowTop') end xlobj~ActiveSheet~Paste --Give the file a name outfile = '.\RxXL_Automation_016.xls' --Turn off the alerts xlobj~DisplayAlerts = .false --Save the file if slowdown then do smsg = .infoDlg~new(d_title,'Save the workbook') smsg~Execute('ShowTop') end xlobj~ActiveSheet~SaveAs(outfile) --Close the Workbook if slowdown then do smsg = .infoDlg~new(d_title,'Close the workbook') smsg~Execute('ShowTop') end xlobj~WorkBooks(1)~Close(SaveAll) --Quit Excel if slowdown then do smsg = .infoDlg~new(d_title,'Quit Excel') smsg~Execute('ShowTop') end xlobj~Quit exit ::requires "WINSYSTM.CLS" ::requires 'oodwin32.cls' ::class infoDlg subclass userdialog public ::method Init expose width height d_title d_text use arg d_title, d_text self~Init:super() width = 350 height = 45 rc=self~CreateCenter(width,height,d_title,,,'Arial',10) ::method DefineDialog expose width height d_title d_text forward class(super) continue self~AddButton( 1,width-60 ,height-20,50,15,'OK','Ok','DEFAULT') self~AddText(1,5,350,15,d_text) ::method Ok self~OK:super return self~finished