how can use a "xl" Implement "xlclass" and "xlApplication" for two purposes

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
cgx5871
Posts: 315
Joined: 26 Jul 2018, 14:02

how can use a "xl" Implement "xlclass" and "xlApplication" for two purposes

Post by cgx5871 » 25 Nov 2022, 13:48

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
		}
	}
}
I want to implement an xl with a
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)
   }
}

Return to “Ask for Help (v1)”