AutoHotkey Community

It is currently May 27th, 2012, 11:49 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: August 5th, 2010, 8:21 pm 
Offline

Joined: June 29th, 2010, 1:01 pm
Posts: 123
OK, I'M CALLING COM_Init()

I'm also using excel 2007, and here is a COMPLETE RUNNING AHK SCRIPT of the test case:

Code:
; Orbiter_runner  program.
;  -This is a test runner program for excel. it just loads up 10 numbers in the first column
;   and then adds the "=row()" function to the 11th row. 
;   
;
;100805 JL  First creation.  By including the Com.ahk library, we can call ~ something ~ (VB??)
;           to get run all kinds of goodies in the excel world. I would like to:
;
;           1) get the row count used and return it to a variable in this script.
;           2) read a cell and return its value to a variable in this script.
;
;
;
;
;
;
; AutoHotkey Version: 1.x
; Language:       English
; Platform:       Win9x/NT
; Author:         A.N.Other <myemail@nowhere.com>
;
; Script Function:
;   Template script (you can customize this template by editing "ShellNew\Template.ahk" in your Windows folder)
;

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#include %a_scriptdir%\com.ahk


Run, excel, C:\My Documents, max, exl_pid


; lets set up some data, we will load the last row with the "=row()" function, but this may not
; be the best way to get the row count.

WinWait, Microsoft Excel ,
IfWinNotActive, Microsoft Excel , , WinActivate, Microsoft Excel ,
WinWaitActive, Microsoft Excel ,
MouseClick, left,  506,  13
Sleep, 100
Send, {F5}
WinWait, Go To,
IfWinNotActive, Go To, , WinActivate, Go To,
WinWaitActive, Go To,
Send, a1{ENTER}
WinWait, Microsoft Excel ,
IfWinNotActive, Microsoft Excel , , WinActivate, Microsoft Excel ,
WinWaitActive, Microsoft Excel ,
Sleep, 50
Send, 5{ENTER}
Sleep, 50
Send,5{ENTER}
Sleep, 50
Send,2{ENTER}
Sleep, 50
Send,4{ENTER}
Sleep, 50
Send,6{ENTER}
Sleep, 50
Send,5{ENTER}
Sleep, 50
Send,3{ENTER}
Sleep, 50
Send,6{ENTER}
Sleep, 50
Send,9{ENTER}
Sleep, 50
Send,10{ENTER}
Sleep, 50
Send,{CTRLDOWN}{HOME}{CTRLUP}
Sleep, 50
Send,{CTRLDOWN}{END}{CTRLUP}
Sleep, 50
Send,{DOWN}
Sleep, 50
Send,=row{SHIFTDOWN}90{SHIFTUP}{ENTER}
Sleep, 50


; ok we have data how do we retrieve the number of rows back into a variable of this script?
msgbox, waiting on B1.

COM_Init()

pxl := COM_GetActiveObject("Excel.Application")

while COM_Invoke(pxl, "ActiveSheet.Range(""b1"").Value") = ""
   sleep, 100
COM_Release(pxl), COM_Term()
MsgBox,  B1 updated, Done!

msgbox, runner done(%0%).`n%1%`n%2%`n%3%`n
exitapp, 5000
; end of program.


It will open excel, and fill in the data for the test, hit a msgbox, waiting on B1, break just before I get the error message. If you click ok on the message box, I get the error:

___________________________________ X
COM Error Notification

Function Name: "Range"
ERROR: The COM Object may not be a valid Dispatch Object!
First ensure that COM Library has been initialized through COM_Init().
0

Will Continue?

Yes No
_________________________________________________


So what is wrong here?

The above code should be cut and pasteable to anyone with ahk and excel installed.




TIA,

Jon


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2010, 12:21 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
Moderator - this post should go in this thread: http://www.autohotkey.com/forum/viewtop ... ht=#374195

You're accessing an invisible Excel process - one that does not have an ActiveSheet. Therefore, the ActiveSheet COM Object from which "Range" is being called is not "a valid Dispatch Object!" If you're lost here, open the task manager. You will notice there is more than one Excel Process running. Try this:
Code:
COM_Init()
ControlGet, hwnd, hwnd, , Excel71, ahk_class XLMAIN ; get Control HWND
XLwin := COM_AccessibleObjectFromWindow(hwnd,-16) ; access Window COM Obj
pxl := COM_Invoke(XLwin, "Application"), COM_Release(XLwin) ; access the XL App
while COM_Invoke(pxl, "ActiveSheet.Range[b1].Value") = ""
   sleep, 100
MsgBox,
COM_Release(pxl), COM_Term()
NOTE - untested & quickly written!

Additional NOTE - you may want to use AHKL - considering the same code would be:
Code:
ControlGet, hwnd, hwnd, , Excel71, ahk_class XLMAIN
pxl := COM_AccessibleObjectFromWindow(hwnd,-16).Application
while pxl.ActiveSheet.Range("b1").Value = ""
   sleep, 100
MsgBox,

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2010, 1:42 am 
Offline

Joined: June 29th, 2010, 1:01 pm
Posts: 123
thanks again jethrow,


I'll give a full report in the morning on how it turns out and clean up my dual threads

I don't understand the "invisible Excel process"/ "missing activesheet" I'll check things out more with the task manager when I'm back at work where I have Excel 2007, but from what I supplied its not intuitive. I mean If you look at the supplied ahk script, the ahk script itself LAUNCHES the excel window. I am able to actively write to the various cells of the Book1 sheet. how can that be invisible and/or missing?

Its the active window for pete's sake,


Secondly, How was I going to be able to figure this out on my own? I mean I feel a little guilty running to this website for all this stuff, but I'll be damn'ed if I could of figured out the controlget, com_accessibleobjectfromwindow...-16, Invoke ... on my own.

Is there a document somewhere where this Com runstream is explained that I can read?




- Jon


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2010, 3:27 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
jleslie48 wrote:
how can that be invisible and/or missing?
Its the active window for pete's sake,
Run, Excel will create a new Excel process. Excel silently keeps an Excel process running for quick launching purposes, after the first launch. Therefore, if there was a silent Excel process running, and you Run, Excel, you will have 2 separate Excel processes. However, GetActiveObject will access the original (silent) one. This will not have an ActiveWorkSheet, as you would be able to see with this code:
Code:
COM_Init()
pxl := COM_GetActiveObject("Excel.Application")
COM_Invoke(pxl, "Visible=", "True")
COM_Release(pxl), COM_Term()


jleslie48 wrote:
How was I going to be able to figure this out on my own?
In the AHK world, I wouldn't expect you to (though I have shown it in Forum Code before). Sean told me - I'm telling you.

Quote:
I'll be damn'ed if I could of figured out the controlget, com_accessibleobjectfromwindow...-16, Invoke
Or blessed ... :P :
- ControlGet
- AccessibleObjectFromWindow
(I'm unable to find a link for the constant "OBJID_NATIVEOM := -16", but it correstponds to the dwObjectID param)
- As the function implies, it returns an Excel Window Object
- and finally, the Application Method
NOTE - pxl = Pointer to the eXceL application object

:wink: 8)

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2010, 1:04 pm 
Offline

Joined: June 29th, 2010, 1:01 pm
Posts: 123
well here's the code now:

Code:
COM_Init()
ControlGet, hwnd, hwnd, , Excel71, ahk_class XLMAIN ; get Control HWND
XLwin := COM_AccessibleObjectFromWindow(hwnd,-16) ; access Window COM Obj
pxl := COM_Invoke(XLwin, "Application"), COM_Release(XLwin) ; access the XL App
while COM_Invoke(pxl, "ActiveSheet.Range(""B1"").Value") = ""
   sleep, 100
MsgBox,
COM_Release(pxl), COM_Term()

MsgBox,  B1 updated, Done!


And I can click past the msgbox, waiting on b1 and the program doesn't crash. I can then click in the spread sheet, and move around with the mouse or arrow buttons, the on the first keystroke on any cell of the sheet, it doesn't even have to be cell B1, I get:

------------------------------------ X
COM Error Notification

Function Name: "ActiveSheet"
ERROR: Call was rejected by callee.
(0x80010001)

Will Continue?

Yes No
---------------------------------------


I've tried both syntax statements for the while statement:

Code:
;while COM_Invoke(pxl, "ActiveSheet.Range(""B1"").Value") = ""
while COM_Invoke(pxl, "ActiveSheet.Range[b1].Value") = ""



-jon


Latest full script (not working):
Code:
; Orbiter_runner  program.
;  -This is a test runner program for excel. it just loads up 10 numbers in the first column
;   and then adds the "=row()" function to the 11th row. 
;   
;
;100805 JL  First creation.  By including the Com.ahk library, we can call ~ something ~ (VB??)
;           to get run all kinds of goodies in the excel world. I would like to:
;
;           1) get the row count used and return it to a variable in this script.
;           2) read a cell and return its value to a variable in this script.
;
;
;
;
;
;
; AutoHotkey Version: 1.x
; Language:       English
; Platform:       Win9x/NT
; Author:         A.N.Other <myemail@nowhere.com>
;
; Script Function:
;   Template script (you can customize this template by editing "ShellNew\Template.ahk" in your Windows folder)
;

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#include %a_scriptdir%\com.ahk


Run, excel, C:\My Documents, max, exl_pid


; lets set up some data, we will load the last row with the "=row()" function, but this may not
; be the best way to get the row count.

WinWait, Microsoft Excel ,
IfWinNotActive, Microsoft Excel , , WinActivate, Microsoft Excel ,
WinWaitActive, Microsoft Excel ,
MouseClick, left,  506,  13
Sleep, 100
Send, {F5}
WinWait, Go To,
IfWinNotActive, Go To, , WinActivate, Go To,
WinWaitActive, Go To,
Send, a1{ENTER}
WinWait, Microsoft Excel ,
IfWinNotActive, Microsoft Excel , , WinActivate, Microsoft Excel ,
WinWaitActive, Microsoft Excel ,
Sleep, 50
Send, 5{ENTER}
Sleep, 50
Send,5{ENTER}
Sleep, 50
Send,2{ENTER}
Sleep, 50
Send,4{ENTER}
Sleep, 50
Send,6{ENTER}
Sleep, 50
Send,5{ENTER}
Sleep, 50
Send,3{ENTER}
Sleep, 50
Send,6{ENTER}
Sleep, 50
Send,9{ENTER}
Sleep, 50
Send,10{ENTER}
Sleep, 50
Send,{CTRLDOWN}{HOME}{CTRLUP}
Sleep, 50
Send,{CTRLDOWN}{END}{CTRLUP}
Sleep, 50
Send,{DOWN}
Sleep, 50
Send,=row{SHIFTDOWN}90{SHIFTUP}{ENTER}
Sleep, 50




FileReadLine, line, C:\testfile.txt, 1


; ok we have data how do we retrieve the number of rows back into a variable of this script?
msgbox, waiting on B1.%line%.

; doesn't work, something about invisbile execl and no activeworksheet
;COM_Init()
;pxl := COM_GetActiveObject("Excel.Application")
;while COM_Invoke(pxl, "ActiveSheet.Range(""$B$1"").Value") = ""
;     sleep, 100
;COM_Release(pxl), COM_Term()

COM_Init()
ControlGet, hwnd, hwnd, , Excel71, ahk_class XLMAIN ; get Control HWND
XLwin := COM_AccessibleObjectFromWindow(hwnd,-16) ; access Window COM Obj
pxl := COM_Invoke(XLwin, "Application"), COM_Release(XLwin) ; access the XL App
;while COM_Invoke(pxl, "ActiveSheet.Range(""B1"").Value") = ""
while COM_Invoke(pxl, "ActiveSheet.Range[b1].Value") = ""
   sleep, 100
MsgBox,
COM_Release(pxl), COM_Term()

MsgBox,  B1 updated, Done!

msgbox, runner done(%0%).`n%1%`n%2%`n%3%`n
exitapp, 5000
; end of program.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2010, 2:07 pm 
My bad - the issue is that the "ActiveSheet" isn't accessible when a cell is being modified. The simplest solution would be to turn off the COM Error for the while-loop:
Code:
COM_Error(false)
while COM_Invoke(pxl, "Range[B1].Value") = ""
   sleep, 100
COM_Error(true)

NOTE - I don't recommend turning off the COM Error unless necessary


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2010, 3:37 pm 
Offline

Joined: June 29th, 2010, 1:01 pm
Posts: 123
All Right!!! It's working now!!!!

here's the full working example, for others to try:

Code:
; Orbiter_runner  program.
;  -This is a test runner program for excel. it just loads up 10 numbers in the first column
;   and then adds the "=row()" function to the 11th row.  The program then monitors cell B1 for
;   a value and when it does wakes up loads variables with the number of rows of the spreadsheet,
;   and the value of cell A3 (just to demonstrate a "read" )
;
;   Setup:    1) install authotkey
;             2) install excel 2007
;             3) install com.ahk
;             4) install this file
;   
;
;100805 JL  First creation.  By including the Com.ahk library, we can call ~ something ~ (VB??)
;           to get run all kinds of goodies in the excel world. I would like to:
;
;           1) get the row count used and return it to a variable in this script.
;           2) read a cell and return its value to a variable in this script.
;
;
;
;
;
;
; AutoHotkey Version: 1.x
; Language:       English
; Platform:       Win9x/NT
; Author:         A.N.Other <myemail@nowhere.com>
;
; Script Function:
;   Template script (you can customize this template by editing "ShellNew\Template.ahk" in your Windows folder)
;

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#include %a_scriptdir%\com.ahk


Run, excel, C:\My Documents, max, exl_pid


; lets set up some data, we will load the last row with the "=row()" function, but this may not
; be the best way to get the row count.

WinWait, Microsoft Excel ,
IfWinNotActive, Microsoft Excel , , WinActivate, Microsoft Excel ,
WinWaitActive, Microsoft Excel ,
MouseClick, left,  506,  13
Sleep, 100
Send, {F5}
WinWait, Go To,
IfWinNotActive, Go To, , WinActivate, Go To,
WinWaitActive, Go To,
Send, a1{ENTER}
WinWait, Microsoft Excel ,
IfWinNotActive, Microsoft Excel , , WinActivate, Microsoft Excel ,
WinWaitActive, Microsoft Excel ,
Sleep, 50
Send, 5{ENTER}
Sleep, 50
Send,5{ENTER}
Sleep, 50
Send,2{ENTER}
Sleep, 50
Send,4{ENTER}
Sleep, 50
Send,6{ENTER}
Sleep, 50
Send,5{ENTER}
Sleep, 50
Send,3{ENTER}
Sleep, 50
Send,6{ENTER}
Sleep, 50
Send,9{ENTER}
Sleep, 50
Send,10{ENTER}
Sleep, 50
Send,{CTRLDOWN}{HOME}{CTRLUP}
Sleep, 50
Send,{CTRLDOWN}{END}{CTRLUP}
Sleep, 50
Send,{DOWN}
Sleep, 50
Send,=row{SHIFTDOWN}90{SHIFTUP}{ENTER}
Sleep, 50




FileReadLine, line, C:\testfile.txt, 1


; ok we have data how do we retrieve the number of rows back into a variable of this script?
msgbox, waiting on B1.%line%.

; doesn't work, something about invisbile execl and no activeworksheet
;COM_Init()
;pxl := COM_GetActiveObject("Excel.Application")
;while COM_Invoke(pxl, "ActiveSheet.Range(""$B$1"").Value") = ""
;     sleep, 100
;COM_Release(pxl), COM_Term()

COM_Init()
ControlGet, hwnd, hwnd, , Excel71, ahk_class XLMAIN ; get Control HWND
XLwin := COM_AccessibleObjectFromWindow(hwnd,-16) ; access Window COM Obj
pxl := COM_Invoke(XLwin, "Application"), COM_Release(XLwin) ; access the XL App
COM_Error(false)
;while COM_Invoke(pxl, "ActiveSheet.Range(""B1"").Value") = ""   ; doesn't work with vba syntax???
while COM_Invoke(pxl, "ActiveSheet.Range[b1].Value") = ""        ; this one works. 
   sleep, 100
COM_Error(true)
row_count := COM_Invoke(pxl, "ActiveSheet.UsedRange.Rows.Count")
A3 := COM_Invoke(pxl, "Range[A3].Value")
COM_Release(pxl), COM_Term()

MsgBox,  B1 updated, Done! `nrow_count = %row_count%`n A3 = %a3%`n

msgbox, runner done(%0%).`n%1%`n%2%`n%3%`n
exitapp, 5000
; end of program.


This example even demo's reading an excel cell, and getting the row count. Thanks again for all the help.

As a slightly off-topic follow up, I"m curious about the differences in the syntax between the COM_Invoke from autohotkey and VBA. for example to call up the value of a cell in autohotkey this is the syntax:

while COM_Invoke(pxl, "ActiveSheet.Range[b1].Value") = "" ; this one works.

but this syntax is wrong in VBA. VBA wants:


ActiveSheet.Range("a7").Value = 77777 ' this works in VBA, but not ahk com_invoke, what gives???

I don't understand the difference in syntax, the change between round and square brackets, etc, I would of thought that the COM_Invoke was submitting its second parameter to the VBA interpreter. The fact that the syntax changes implies to me that somethine else is going on.

Here is a VBA subroutine that works as an example:

    Private Sub Worksheet_Change(ByVal Target As Range)



    If Target.Address = "$B$1" Then
    MsgBox "something has changed!!!! JL"
    Open "c:\TESTFILE.txt" For Output Shared As #1
    ' Close before reopening in another mode.
    Print #1, "hello world " & Target.Value
    ' ActiveSheet.Range [a8].Value = 12345 'this doesn't work in VBA, but does in ahk com_invoke,
    ActiveSheet.Range("a7").Value = 77777 ' this works in VBA, but not ahk com_invoke, what gives???

    Close #1
    End If



    End Sub




Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2010, 4:19 pm 
Offline
User avatar

Joined: December 21st, 2007, 3:14 pm
Posts: 3826
Location: Louisville KY USA
Code:
COM_Invoke(pxl, "ActiveSheet.Range[a7].Value",7777)

_________________
No matter what your oppinion Please join this discussion
Formal request to Polyethene
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2010, 4:52 pm 
Offline

Joined: June 29th, 2010, 1:01 pm
Posts: 123
tank wrote:
Code:
COM_Invoke(pxl, "ActiveSheet.Range[a7].Value",7777)



thanks I'll remember that. I was pefectly comfortable with:


Code:
Send, {F5}
WinWait, Go To,
IfWinNotActive, Go To, , WinActivate, Go To,
WinWaitActive, Go To,
Send, a7{ENTER}
Sleep,50
Send,7777{ENTER}


but your's in much cleaner.

I was questioning why the change in syntax however. from vba syntax >range("a7").value< to >range[a7].value<


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2010, 5:00 pm 
Offline
User avatar

Joined: December 21st, 2007, 3:14 pm
Posts: 3826
Location: Louisville KY USA
ahk and vba arent related
ahk has no native support for objects so you must therefore go about things in a very round about way
I might also tell you that com_invoke inserts integers as integers as such 10,11,12 are parameters of value and will not write and numbers larger than 32 bit will truncate.
I am a fool for not pointing this out but for inserts might be better to use
Code:
COM_Invoke_(pxl, "ActiveSheet.Range[a7].Value",8,7777)
which tells it to insert as BSTR and bypasses the above described issues

_________________
No matter what your oppinion Please join this discussion
Formal request to Polyethene
Image


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], BrandonHotkey, MSN [Bot] and 17 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group