AutoHotkey Community

It is currently May 27th, 2012, 5:24 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: February 7th, 2011, 6:33 pm 
Offline

Joined: September 7th, 2004, 9:20 pm
Posts: 275
Location: France
Getting inspiration from ADO COM - Database Query and especially from ADODB Excel Database Query [AHK_L], I wrote a function to interrogate an Excel database with ADO, using AHK_L.
Those who want to improve this function are welcome. For example, the result is returned in the form of a string which can be used with StringSplit to get the results. Anyone who want to modify the function to return an associative array is welcome.
I don't know so well objects and associatives arrays, nor their usage, so I used an old (but well known) solution...
The Excel file must be organised as a database, with each column representing a field, and each line a record.

Now the function :

Entry parameters :
GXD_Base : the workbook - the Excel file (with full path)
GXD_Sheet : the name of the (Work)Sheet of the Workbook on which we want to work, not followed by "$", which is added by the function itself.
GXD_ColsToGet : Column(s) to get
The default value is the "*" character (which means "get all the columns/fields of the base "). You can give a list of columns names, separated by commas.
If the list end with a comma, an error is genrated by SQL, but the function check if it is ok and if not, correct the entry.
GXD_ColToVerif1 and GXD_ColToVerif2 : Column (field) in which we want to check the data.
GXD_Filtre : SQL statement indicating the operation that we want to do (Example : BETWEEN, LIKE, =, ...)
GXD_ValToComp1 and GXD_ValToComp2 : Values to compare. If the value is alpha or contains characters specifics to the LIKE Statement (%-_![]), the function will surround it with two "'". If you have an alphanumeric value (ex : blabla22) or if the values are numeric but specified as text in Excel (ex : 0652), you must to surround it by "'" characters yourself ("'blabal22'" or "'0652'").
GXD_Link : SQL Statement allowing to link two values or statements in an SQL request (AND, OR). Examples :
BETWEEN 20 AND 50 or
Region = 'Quebec' AND Rep = 'Jones'

Return value :
GXD_Records : Recovered datas. Each value of a field of a record recovered is separated from the next field by a semicolon. Each record is separated from the next by the character "|".
It is possible to recover values by using StringSplit to separate records, and then to separate each field of a record.

To test the function, I used the SampleData.xls of ADODB Excel Database Query [AHK_L], which must be in the directory in which you put the ahk file.

Here is the function :
Code:
GXD_Base := A_ScriptDir . "\SampleData.xls"
GXD_Sheet := "Sheet1"

;clipboard := GetXLData(GXD_Base, GXD_Sheet,, "Units", "BETWEEN", 20, "AND",,, 50)
;clipboard := GetXLData(GXD_Base, GXD_Sheet, "Region,Rep,Unit Cost,", "Units", "BETWEEN", "20", "AND",,, 60)
;clipboard := GetXLData(GXD_Base, GXD_Sheet,, "Units", "BETWEEN", 30, "AND",,, 50)
;clipboard := GetXLData(GXD_Base, GXD_Sheet,, "Units", "IN", "(50, 60, 90)")
;clipboard := GetXLData(GXD_Base, GXD_Sheet,, "Units", ">", 90)
;clipboard := GetXLData(GXD_Base, GXD_Sheet, "Region, Rep,Unit Cost,", "Units", "BETWEEN", 30, "AND",,, 60)
;clipboard := GetXLData(GXD_Base, GXD_Sheet, "Region, Rep,Unit Cost,", "Region", "=", "Quebec", "AND", "Rep", "=", "Jones")
;clipboard := GetXLData(GXD_Base, GXD_Sheet, "Region, Rep,Unit Cost,", "Units", "LIKE", "3%")

GetXLData(GXD_Base, GXD_Sheet, GXD_ColsToGet = "*", GXD_ColToVerif1 = "", GXD_Filtre1 = "", GXD_ValToComp1 = "", GXD_Link = "", GXD_ColToVerif2 = "", GXD_Filtre2 = "", GXD_ValToComp2 = "")
{
   adOpenStatic = 3
   adLockOptimistic = 3
   adCmdText = 1
   adApproxPosition := 0x4000

   GXD_Sheet := GXD_Sheet . "$"

   If (GXD_ColsToGet != "*")
   {
      GXD_LColsToGet := StrLen(GXD_ColsToGet)
      If SubStr(GXD_ColsToGet, StrLen(GXD_ColsToGet), 1) = ","
         GXD_ColsToGet := SubStr(GXD_ColsToGet, 1, StrLen(GXD_ColsToGet) - 1)
      If InStr(GXD_ColsToGet, ",")
      {
         If InStr(GXD_ColsToGet, ", ")
            StringReplace, GXD_ColsToGet, GXD_ColsToGet, `,%A_SPACE%, `,, All
         StringSplit, GXD_ColsContent, GXD_ColsToGet, `,]
         Loop, %GXD_ColsContent0%
         {
            If InStr(GXD_ColsContent%A_Index%, A_Space)
               GXD_ColsContent%A_Index% := "``" . GXD_ColsContent%A_Index% . "``"
            GXD_ColsContent := GXD_ColsContent . GXD_ColsContent%A_Index% . ", "
         }
      }
      GXD_ColsToGet := GXD_ColsContent
      If SubStr(GXD_ColsToGet, StrLen(GXD_ColsToGet)-1, 2) = ", "
         GXD_ColsToGet := SubStr(GXD_ColsToGet, 1, StrLen(GXD_ColsToGet) - 2)
   }

   Loop, 2
   {
      If GXD_ColToVerif%A_Index%
      {
         If InStr(GXD_ColToVerif%A_Index%, A_Space)
            GXD_ColToVerif%A_Index% := "``" . GXD_ColToVerif%A_Index% . "``"
      }
      If GXD_ValToComp%A_Index%
      {
         If var is not number
            GXD_ValToComp%A_Index% := "'" . GXD_ValToComp%A_Index% . "'"
      }
   }

   If (GXD_ColToVerif1 and GXD_ValToComp2 and GXD_ColToVerif2 and GXD_Filtre2)
      Request := "SELECT " . GXD_ColsToGet . " FROM [" . GXD_Sheet . "]" . " WHERE " . GXD_ColToVerif1 . " " . GXD_Filtre1 . " " . GXD_ValToComp1 . " " . GXD_Link . " " . GXD_ColToVerif2 . " " . GXD_Filtre2 . " " . GXD_ValToComp2

   If (GXD_ColToVerif1 and GXD_ValToComp2 and !GXD_ColToVerif2 and !GXD_Filtre2)
      Request := "SELECT " . GXD_ColsToGet . " FROM [" . GXD_Sheet . "]" . " WHERE " . GXD_ColToVerif1 . " " . GXD_Filtre1 . " " . GXD_ValToComp1 . " " . GXD_Link . " " . GXD_ValToComp2

   If (GXD_ColToVerif1 and !GXD_ValToComp2 and !GXD_ColToVerif2 and !GXD_Filtre2)
      Request := "SELECT " . GXD_ColsToGet . " FROM [" . GXD_Sheet . "]" . " WHERE " . GXD_ColToVerif1 . " " . GXD_Filtre1 . " " . GXD_ValToComp1

   If (!GXD_ColToVerif1 and !GXD_ValToComp2 and !GXD_ColToVerif2 and !GXD_Filtre2)
      Request := "SELECT " . GXD_ColsToGet . " FROM [" . GXD_Sheet . "]"

   objConnection := ComObjCreate("ADODB.Connection")
   objRecordSet := ComObjCreate("ADODB.Recordset")
   objConnection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" . GXD_Base . ";Extended Properties=""Excel 8.0;HDR=Yes;"";")
   objRecordSet.Open(Request, objConnection, adOpenStatic, adLockOptimistic, adCmdText)

   GXD_NumRec := objRecordSet.RecordCount
   GXD_pFields := objRecordSet.Fields
   GXD_NumFiels := GXD_pFields.Count

   Loop %GXD_NumRec%
   {
      Loop %GXD_NumFiels%
      {
         If A_Index < %GXD_NumFiels%
            GXD_Records := GXD_Records . GXD_pFields.Item(A_Index-1).Value . ";"
         Else
            GXD_Records := GXD_Records . GXD_pFields.Item(A_Index-1).Value
      }
      If A_Index < %GXD_NumRec%
         GXD_Records := GXD_Records . "|"
      objRecordSet.MoveNext
   }

   objRecordSet.Close()
   objConnection.Close()
   objRecordSet := ""
   objConnection := ""   
   
   Return GXD_Records
}

Of course, to make a test, you delete a semicolon before a "clipboard := " that you choose, you save the script and you run it.
Again if you want to improve the function, to make comments or suggestions, you are welcome.
I hope you will find this function usefull.


Last edited by Nemroth on February 12th, 2011, 7:40 pm, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 7th, 2011, 11:12 pm 
Offline

Joined: July 25th, 2006, 9:06 am
Posts: 51
I tried this with your first example and got an error.
Looks to be in Microsoft Visual C++ Runtime Library.

RunTime Error in AutoHotkey.exe
R6025
-Pure Virtual Function Call

means nothing to me, have I not got the latest verion of AHK_L or something.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 8th, 2011, 1:42 am 
Offline

Joined: September 7th, 2004, 9:20 pm
Posts: 275
Location: France
Sorry for your problem but the error message means nothing to me too. I'm not so clever in COM/ADO and AHK_L to understand it.
For me the first example (and the others) works.
Of course you need to have AHK_L. I'm not sure about the minimal version needed but I have the last one.
Did you saved the script in UTF-8 format to make it compatible with AHK_L ?
If so, may be Lexicos can give an answer.
When (in the script) this error occurs ?
Did other users had the same problem ?
Or may be it's an error due to the fact that you don't have Excel on your computer ??? I don't know.


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

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 4 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