Code: Select all
xl:=New xlClass
MsgBox % xl.WinTitle
MsgBox % xl.app.Selection.address ;~ This is normal usage.
MsgBox % xl.Selection.address ;~ This is the usage I want to achieve
class xlClass extends ADODB {
static WinTitle:="ahk_class XLMAIN"
app:=this.xlGet()
__Get(aName){
;~ if !this[aName]
;~ return this.app.Selection.address
}
xlGet() {
ControlGet, hwnd, hwnd, , Excel71,% this.WinTitle
if (!hwnd){
xlapp:=""
} else if (!xlapp){
Window := Acc_ObjectFromWindow(hwnd, -16)
Loop
try
xlapp := Window.Application
catch
ControlSend, Excel71, {esc}, % this.WinTitle
Until !!xlapp
return xlapp
}
}
}
At the same time, it can achieve two purposes of xlclass and xlApplication.
When xlClass has no corresponding item, automatically return xlApplication
What's the best way?
Sorry this is not my native language, this is Google Translate
I don't know if the expression is clear
Code: Select all
; Based on ADOSQL v5.04L - By [VxE]
Class ADODB {
; ===================================================================================================================
; ; Create a new connection object. > www.w3schools.com/asp/ado_ref_connection.asp
; ===================================================================================================================
__New() {
This.LastError := This.LastStatement := ""
ComObjError(0) ; We'll manage COM errors manually.
; If something goes wrong here, return blank and set the error message.
If !(oCon := ComObjCreate("ADODB.Connection")) {
ComObjError(1)
ErrorLevel := "Error"
This.LastError := "Fatal Error: ADODB is not available."
Return ""
}
oCon.ConnectionTimeout := 15 ; Allow 15 seconds to connect to the server. Default is 15.
oCon.CursorLocation := 3 ; Use a client-side cursor server.
oCon.CommandTimeout := 60 ; A generous 1 minute timeout on the actual SQL statement. Default is 30.
This.Connection := oCon
ComObjError(1)
}
; ===================================================================================================================
; If the connection is still open, we close it.
; ===================================================================================================================
__Delete() {
If (This.Connection)
This.Close()
}
; ===================================================================================================================
; Connect to a database. > www.w3schools.com/asp/met_conn_open.asp
; ===================================================================================================================
Open(ConnectionString) {
This.LastError := This.LastStatement := ""
ComObjError(0) ; We'll manage COM errors manually.
This.Connection.Open(ConnectionString) ; Open the connection.
If (ComError := A_LastError) {
This.GetError()
ComObjError(1)
ErrorLevel := ComError
Return ""
}
ComObjError(1)
Return True
}
; ===================================================================================================================
; Close the connection. > www.w3schools.com/asp/met_conn_close.asp
; ===================================================================================================================
Close() {
This.LastError := This.LastStatement := ""
ComObjError(0) ; We'll manage COM errors manually.
This.Connection.Close()
This.Connection := ""
ComObjError(1)
Return True
}
; ===================================================================================================================
; Execute a non-query statement. > www.w3schools.com/asp/met_conn_execute.asp
; ===================================================================================================================
Exec(SQLStatement) {
This.LastError := "", This.LastStatement := SQLStatement
ComObjError(0) ; We'll manage COM errors manually.
Dummy := This.Connection.Execute(SQLStatement)
If (ComError := A_LastError) {
This.GetError()
ComObjError(1)
ErrorLevel := ComError
Return ""
}
ComObjError(1)
Return True
}
; ===================================================================================================================
; Execute a query statement and get the recordset. > www.w3schools.com/asp/ado_ref_recordset.asp
; ===================================================================================================================
Query(QueryStatement) {
This.LastError := "", This.LastStatement := QueryStatement
ComObjError(0) ; We'll manage COM errors manually.
Recordset := This.Connection.Execute(QueryStatement)
If (ComError := A_LastError) {
This.GetError()
ComObjError(1)
ErrorLevel := ComError
Return ""
}
Result := {} ; This is a 3-dimensional array.
While IsObject(Recordset) {
If !(Recordset.BOF && Recordset.EOF) || !(Recordset.State) { ; Recordset is empty, so we skip it.
; A row-returning operation returns an open Recordset
Fields := Recordset.Fields
Columns := Fields.Count
Result.Push(Query := [])
Query.Push(Row := [])
Loop % Columns ; Put the column names in the first row.
Row[A_Index] := Fields.Item(A_Index - 1).Name
While !(Recordset.EOF) { ; While the record pointer is not at the end of the Recordset...
Query.Push(Row := [])
Row.SetCapacity(Columns) ; Might improve performance on huge tables??
Loop % Columns
Row[A_Index] := Fields.Item(A_Index - 1).Value
Recordset.MoveNext() ; move the record pointer to the next row of values
If (ComError := A_LastError) {
This.GetError()
ComObjError(1)
ErrorLevel := ComError
Return ""
}
}
}
Recordset := Recordset.NextRecordset() ; Get the next Recordset.
}
ComObjError(1)
Return Result
}
; ===================================================================================================================
; Convert a result object as returned from Query() into a string.
; ===================================================================================================================
ToString(Result, ColDelim := "|", RowDelim := "`n") {
Str := ""
For I1, Table In Result {
Str .= RowDelim
For I2, Row In Table {
Str .= RowDelim
For I3, Column In Row
Str .= (I3 > 1 ? "|" : "") . Column
}
}
Return SubStr(Str, 3)
}
; ===================================================================================================================
; Get the last error.
; ===================================================================================================================
GetError() {
This.LastError := LastErrors := ""
For Item In This.Connection.Errors
LastErrors .= "`n`n" . Item.Description . "`n"
. "Error number: " . Item.Number . "`n"
. "Error source: " . Item.Source . "`n"
. "Native error: " . Item.NativeError . "`n"
. "SQL state: " . Item.SQLState
This.LastError := SubStr(LastErrors, 3)
}
}