Update 17.11.2011.: Latest version by hoppfrosch here.
______________________
Original post: (obsolete code)
I'm not sure is this for
Scripts & Functions or
Ask for Help forum. Anyway, this is the first time I tried to code a
object for AHK_L, so I would like to hear:
-
Am I doing it right?
-
Am I going in right direction?
-
other comments and suggestions.
Main purpose of object is to search the columns in a database for a specified string. Can set/get cells, do a search through multiple columns, add rows, etc. Not finished, just a prerelease. Here is what I have done for now;
oTable.ahk
Code:
;===Description=========================================================================
; [object] Table - prerelease by Learning one
;===Functions===========================================================================
Table_ObjCreate(FilePath,ColumnNames, ColumnsDelimiter="`t", RowsDelimiter= "`n") { ; creates object and its methods
static base := Table_Base("SetCell GetCell Save SaveAs Open Reload Search SearchColumn ChangeDelimiters Get Set Add Replace", "Table_m")
obj := Object("base", base)
IfNotExist, %FilePath%
FileAppend, , %FilePath%, UTF-8
else
{
oFile := FileOpen(FilePath, "r `n", "UTF-8")
obj.c := oFile.Read()
oFile.Close()
}
obj.cn := ColumnNames, obj.fp := FilePath
obj.cd := ColumnsDelimiter, obj.rd := RowsDelimiter
return obj
}
Table_Base(list, prefix) {
base := Object()
Loop Parse, list, %A_Space%
base[A_LoopField] := prefix A_LoopField
Return base
}
Table_mGetCell(obj, ColumnName, RowNumber) {
ColumnsDelimiter := obj.cd, RowsDelimiter := obj.rd, ColumnNames := obj.cn
Var := obj.c
ColIndex := Table_ColumnNames2Num(obj ,ColumnName)
if ColIndex =
return
Loop, parse, var, %RowsDelimiter%
{
if (A_Index = RowNumber)
{
CurRow := A_LoopField
Loop, parse, CurRow, %ColumnsDelimiter%
{
if (A_Index = ColIndex)
return A_LoopField
}
}
}
}
Table_mSetCell(obj, ColumnName, RowNumber, NewCellContents, Save=1) {
ColumnsDelimiter := obj.cd, RowsDelimiter := obj.rd, ColumnNames := obj.cn
Var := obj.c
ColIndex := Table_ColumnNames2Num(obj ,ColumnName)
if ColIndex =
return
Loop, parse, var, %RowsDelimiter%
{
if (A_Index = RowNumber)
{
CurRow := A_LoopField
Loop, parse, CurRow, %ColumnsDelimiter%
{
if (A_Index = ColIndex)
NewCurRow .= NewCellContents ColumnsDelimiter
else
NewCurRow .= A_LoopField ColumnsDelimiter
}
NewCurRow := Trim(NewCurRow, ColumnsDelimiter)
NewTableContents .= NewCurRow RowsDelimiter
}
else
NewTableContents .= A_LoopField RowsDelimiter
}
NewTableContents := Trim(NewTableContents, RowsDelimiter)
obj.c := NewTableContents
if Save
obj.Save()
}
Table_mSearchColumn(obj, ColumnsToSearch, StringToSearch) {
ColumnsDelimiter := obj.cd, RowsDelimiter := obj.rd, ColumnNames := obj.cn
Var := obj.c
ColNumbersToSearch := Table_ColumnNames2Num(obj ,ColumnsToSearch)
if ColNumbersToSearch =
return
Loop, parse, var, %RowsDelimiter%
{
CurRow := A_LoopField
if CurRow is space
continue
Loop, parse, CurRow, %ColumnsDelimiter%
{
if A_Index in %ColNumbersToSearch%
{
if A_LoopField contains %StringToSearch%
FoundRowsList .= CurRow RowsDelimiter
}
}
}
Return Trim(FoundRowsList, RowsDelimiter)
}
Table_mSearch(obj, StringToSearch) {
ColumnsDelimiter := obj.cd, RowsDelimiter := obj.rd, ColumnNames := obj.cn
Var := obj.c
Loop, parse, var, %RowsDelimiter%
{
if A_LoopField contains %StringToSearch%
FoundRowsList .= A_LoopField RowsDelimiter
}
Return Trim(FoundRowsList, RowsDelimiter)
}
Table_mSave(obj) {
Contents := obj.c, FilePath := obj.fp
oFile := FileOpen(FilePath, "w `n", "UTF-8") ; creates a new file, overwriting any existing file.
oFile.Write(Contents)
oFile.Close()
}
Table_mSaveAs(obj,NewFilePath) {
Contents := obj.c
oFile := FileOpen(NewFilePath, "w `n", "UTF-8") ; creates a new file, overwriting any existing file.
oFile.Write(Contents)
oFile.Close()
}
Table_mOpen(obj) {
FilePath := obj.fp
Run, notepad "%FilePath%"
}
Table_mReload(obj) {
FilePath := obj.fp
oFile := FileOpen(FilePath, "r `n", "UTF-8")
obj.c := oFile.Read()
oFile.Close()
}
Table_mChangeDelimiters(obj, NewColumnsDelimiter, NewRowsDelimiter, Save=1) {
ColumnsDelimiter := obj.cd, RowsDelimiter := obj.rd, ColumnNames := obj.cn
Var := obj.c
StringReplace, var, var, %ColumnsDelimiter%, %NewColumnsDelimiter%, all
StringReplace, var, var, %RowsDelimiter%, %NewRowsDelimiter%, all
obj.c := var
obj.cd := NewColumnsDelimiter, obj.rd := NewRowsDelimiter
if Save
obj.Save()
}
Table_mGet(obj) {
return obj.c
}
Table_mSet(obj, NewTableContents, Save=1) {
obj.c := NewTableContents
if Save
obj.Save()
}
Table_mAdd(obj, NewRow, Save=1) {
RowsDelimiter := obj.rd, Contents := obj.c
NewRow := Trim(NewRow, RowsDelimiter)
obj.c := Contents RowsDelimiter NewRow
if Save
obj.Save()
}
Table_mReplace(obj, SearchText, ReplaceText="", Save=1) {
Var := obj.c
StringReplace, Var, Var, %SearchText%, %ReplaceText%, All
obj.c := var
if Save
obj.Save()
return ErrorLevel
}
Table_ColumnNames2Num(obj, ColumnsToSearch) {
ColumnNames := obj.cn
Loop, parse, ColumnsToSearch, |
{
CurColName := A_LoopField
Loop, parse, ColumnNames, |
{
if (A_LoopField = CurColName)
Found .= A_Index ","
}
}
return Trim(Found, ",")
}
Testing script:
Code:
#Include, oTable.ahk
;===Auto-execute========================================================================
FilePath := A_ScriptDir "\MyTable.txt"
IfNotExist, %FilePath%
Gosub, CreateSampleFile
oTable := Table_ObjCreate(FilePath, "First name|Last name|Occupation|Notes") ; create table object from file, define column names
return
;===Hotkeys for testing==================================================================
F1::MsgBox, % oTable.SearchColumn("Occupation","Driver") ; search for "Driver" (match only in "occupation" column)
F2::MsgBox, % oTable.SearchColumn("First name|Last name","Jack") ; search for "Jack" (match in "First name" and "Last name" columns)
F3::MsgBox, % oTable.Search("Driver") ; search for "driver" (match anywhere)
F4::MsgBox, % oTable.Get() ; get object's contents and show it in MsgBox
F5::oTable.Open() ; open object's FilePath in notepad
F6::oTable.Add("Mary" A_Tab "Gills" A_Tab "Nurse" A_Tab) ; adds a new row
F7::MsgBox, % oTable.GetCell("Last name",4) ; get value from ["last name" column, 4. row]
F8::oTable.SetCell("First name",1,"Bobby") ; set ["first name" column, 1. row] to value "Bobby"
/*;===some other examples===
oTable.Reload() ; reads object's file again and stores it in object's contents
oTable.Save() ; saves object's contents in its file
oTable.SaveAs(A_ScriptDir "\MyTable backup.txt") ; saves object's contents in new file (make a backup)
oTable.ChangeDelimiters("|","#") ; change columns and rows delimiters
*/
;===Subroutines=========================================================================
CreateSampleFile:
SampleFileContents =
(
Jack%A_Tab%Gates%A_Tab%Driver%A_Tab%
Mark%A_Tab%Weber%A_Tab%Student%A_Tab%His father is a driver.
Jim%A_Tab%Tucker%A_Tab%Driver%A_Tab%
Jill%A_Tab%Lochte%A_Tab%Artist%A_Tab%
Jessica%A_Tab%Hickman%A_Tab%Student%A_Tab%
Mary%A_Tab%Jones%A_Tab%Teacher%A_Tab%Her favorite song is "Driver"
Lenny%A_Tab%Stark%A_Tab%Driver%A_Tab%
Jack%A_Tab%Black%A_Tab%Actor%A_Tab%
Tony%A_Tab%Jackman%A_Tab%Surfer%A_Tab%
Jonny%A_Tab%Poor%A_Tab%Beggar%A_Tab%
)
oFile := FileOpen(FilePath, "w `n", "UTF-8")
oFile.Write(SampleFileContents)
oFile.Close()
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ExitApp
Pause::
Suspend
Pause,,1
return
Escape::
Suspend
ExitApp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;