jeeswg wrote:- I recently found out that with the Excel_Get function, by specifying the 2nd parameter, you can latch onto a specific workbook via a control (e.g. EXCEL71, EXCEL72).
You might find this GetExcel class useful in some situations.
https://autohotkey.com/boards/viewtopic ... 76#p134876
Code: Select all
; Lexikos example to get all active objects
for name, obj in GetActiveObjects()
list .= name " -- " ComObjType(obj, "Name") "`n"
MsgBox %list%
; FanaticGuru example of GetExcel class method Xls
Xls := GetExcel.Xls()
for index, Xl in Xls
for Workbook in Xl.Workbooks
MsgBox % Workbook.name "`n" Workbook.Windows(1).Visible
; FanaticGuru example of GetExcel class method Wbs
Wbs := GetExcel.Wbs(,1) ; only visible workbooks
for index, Wb in Wbs
MsgBox % Wb.Name "`n" Wb.Windows(1).Visible
class GetExcel
{
Xls(Needle := "")
{
Xls := {}
for index, obj in GetActiveObjects()
{
try
Name := obj.Application.ActiveWorkbook.Name
catch
continue
if (RegExMatch(index, "(^|\\)" Name "$") and RegExMatch(Name, Needle))
Xls.Push(obj.Application)
}
return Xls
}
Wbs(Needle := "", Visible := "")
{
Wbs := {}
Xls := GetExcel.Xls()
for index, Xl in Xls
for Workbook in Xl.Workbooks
if RegExMatch(Workbook.Name, Needle)
if (Visible = 1 and Workbook.Windows(1).Visible)
Wbs.Push(Workbook)
else if (Visible = 0 and not Workbook.Windows(1).Visible)
Wbs.Push(Workbook)
else if (Visible = "")
Wbs.Push(Workbook)
return Wbs
}
}
; GetActiveObjects v1.0 by Lexikos
; http://ahkscript.org/boards/viewtopic.php?f=6&t=6494
GetActiveObjects(Prefix:="", CaseSensitive:=false) {
objects := {}
DllCall("ole32\CoGetMalloc", "uint", 1, "ptr*", malloc) ; malloc: IMalloc
DllCall("ole32\CreateBindCtx", "uint", 0, "ptr*", bindCtx) ; bindCtx: IBindCtx
DllCall(NumGet(NumGet(bindCtx+0)+8*A_PtrSize), "ptr", bindCtx, "ptr*", rot) ; rot: IRunningObjectTable
DllCall(NumGet(NumGet(rot+0)+9*A_PtrSize), "ptr", rot, "ptr*", enum) ; enum: IEnumMoniker
while DllCall(NumGet(NumGet(enum+0)+3*A_PtrSize), "ptr", enum, "uint", 1, "ptr*", mon, "ptr", 0) = 0 ; mon: IMoniker
{
DllCall(NumGet(NumGet(mon+0)+20*A_PtrSize), "ptr", mon, "ptr", bindCtx, "ptr", 0, "ptr*", pname) ; GetDisplayName
name := StrGet(pname, "UTF-16")
DllCall(NumGet(NumGet(malloc+0)+5*A_PtrSize), "ptr", malloc, "ptr", pname) ; Free
if InStr(name, Prefix, CaseSensitive) = 1 {
DllCall(NumGet(NumGet(rot+0)+6*A_PtrSize), "ptr", rot, "ptr", mon, "ptr*", punk) ; GetObject
; Wrap the pointer as IDispatch if available, otherwise as IUnknown.
if (pdsp := ComObjQuery(punk, "{00020400-0000-0000-C000-000000000046}"))
obj := ComObject(9, pdsp, 1), ObjRelease(punk)
else
obj := ComObject(13, punk, 1)
; Store it in the return array by suffix.
objects[SubStr(name, StrLen(Prefix) + 1)] := obj
}
ObjRelease(mon)
}
ObjRelease(enum)
ObjRelease(rot)
ObjRelease(bindCtx)
ObjRelease(malloc)
return objects
}
Unlike the Excel_Get function that goes from a window to the COM object associated with that window this class queries the table of all active COM objects and then finds the ones that are Excel objects. It is preliminary for cases when you have more than one application of Excel running and you need to access all of them or a specific one. It allows you to easily get all Workbooks that match a needle supplied regardless of how many applications of Excel are running. ie You can have 5 workbooks in 1 application of Excel or 5 applications of Excel running with 1 workbook each. Does not matter, it will find the workbook you are looking for based on a regex needle.
FG