Dialog StringGrid Sort Sample

General Macro Scheduler discussion

Moderators: Dorian (MJT support), JRL

Post Reply
User avatar
JRL
Automation Wizard
Posts: 3501
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Dialog StringGrid Sort Sample

Post by JRL » Fri May 03, 2013 5:06 am

Here's a method for picking a string grid header and sorting the entire grid by that column. I don't know why this fails if you pick the file size column. I have the same issue on the original script I came up with this method for. It has two numeric columns and fails if you pick either of them. Tried removing the quotes from the input and that did not seem to help.

This relies on the SQLToCSV vbscript Marcus posted a while back and sorts using SQL "order by" on a csv file.

I have an idea for making the grid reverse sort also but have not typed it up yet. Anyone else think they can do it? There's 20 points in it if you do.

Hope someone finds this useful.

Code: Select all

VBSTART
  Sub SQLToCSV(connection_string,sql_string,output_file)
    Dim outFile, objConnection, objRecordSet, strSQL, intCount
    set outFile = CreateObject("Scripting.FileSystemObject").CreateTextFile(output_file)
    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.open connection_string
    Set objRecordSet = objConnection.Execute(sql_string)
    for intcount = 0 to objRecordSet.fields.count -1
        if intcount <> objRecordSet.fields.count-1 then
            outFile.write """" & objRecordSet.fields(intcount).name & ""","
        else
            outFile.write """" & objRecordSet.fields(intcount).name & """"
        end if
    next
    outFile.writeline ""
    do while not objRecordSet.eof
        for intcount = 0 to objRecordSet.fields.count - 1
            if intcount <> objRecordSet.fields.count - 1 then
                outFile.write """" & objRecordSet.fields(intcount).value & ""","
            else
                outFile.write """" & objRecordSet.fields(intcount).value & """"
            end if
        next
        outFile.writeline ""
        objRecordSet.movenext
    loop
    objRecordSet.Close
    set objRecordSet = Nothing
    objConnection.Close
    set objConnection = Nothing
    outFile.Close
    set outFile = Nothing
  End Sub
VBEND

Dialog>Dialog1
object Dialog1: TForm
  Left = 470
  Top = 142
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'Grid Sort Test'
  ClientHeight = 770
  ClientWidth = 550
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  Position = poScreenCenter
  TextHeight = 13
  object MSStringGrid1: tMSStringGrid
    Left = 0
    Top = 0
    Width = 550
    Height = 770
    ColCount = 5
    DefaultRowHeight = 18
    DrawingStyle = gdsGradient
    FixedColor = 8388863
    FixedCols = 0
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    Options = [goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goFixedColClick, goFixedRowClick, goFixedHotTrack]
    ParentFont = False
    ParentShowHint = False
    ShowHint = True
    TabOrder = 0
    ColWidths = (
      40
      150
      75
      75
      75)
  end
end
EndDialog>Dialog1

AddDialogHandler>Dialog1,MSStringGrid1,OnFixedCellClick,Sort

GetFileList>c:\*.*,vData
Separate>vData,;,vLine

Let>vDirList="Line","File","Size","Date","Time"%crlf%
Let>kk=0
Repeat>kk
  Add>kk,1
  Let>value=vLine_%kk%
  FileSize>value,vFileSize
  FileDate>value,vFileDate
  FileTime>value,vFileTime
  If>{%kk%<(%vLine_Count%-1)}
    ConCat>vDirList,"%kk%","%value%","%vFileSize%","%vFileDate%","%vFileTime%",%crlf%
  Else
    ConCat>vDirList,"%kk%","%value%","%vFileSize%","%vFileDate%","%vFileTime%"
  EndIf
Until>kk={%vLine_Count%-1}

DeleteFile>%temp_dir%DirList.csv

SetDialogObjectFont>Dialog1,MSStringGrid1,Arial,10,1,0
SetDialogProperty>Dialog1,MSStringGrid1,LoadFromCSV,vDirList
WriteLn>%temp_dir%DirList.csv,wres,vDirList

Show>Dialog1,res1

SRT>Sort
  DeleteFile>%temp_dir%SortedDirList.csv
  If>Sort_ACol=1
    Let>Sort_Col=File
  EndIf
  If>Sort_ACol=2
    Let>Sort_Col=Size
  EndIf
  If>Sort_ACol=3
    Let>Sort_Col=Date
  EndIf
  If>Sort_ACol=4
    Let>Sort_Col=Time
  EndIf

  Let>Con=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%temp_dir%;Extended Properties='text;HDR=YES;FMT=Delimited'
  Let>SQL=SELECT * FROM DirList.csv order by %Sort_Col%
  Let>vFile=%temp_dir%SortedDirList.csv

  VBRun>SQLToCSV,con,SQL,vFile

  ReadFile>%temp_dir%SortedDirList.csv,vDirList
  SetDialogProperty>Dialog1,MSStringGrid1,LoadFromCSV,vDirList
End>Sort

User avatar
jpuziano
Automation Wizard
Posts: 1085
Joined: Sat Oct 30, 2004 12:00 am

Post by jpuziano » Fri May 03, 2013 6:28 pm

Facinating, thanks JRL... this will be useful.

I am even more interested in the error that happens when you click on one of the two numeric columns:

---------------------------
Macro Scheduler
---------------------------
:-2147467259
Line 7, Column 4
---------------------------
OK Abort
---------------------------


I have another script that occasionally throws an error very similar to that so perhaps finding out what this error is will help me with mine as well.

Marcus - Please try this script, verify that clicking on some of the columns re-sorts wonderfully... however clicking on one or the 2 numeric columns throws the above error... then the big question is, what is the error telling us and how do we avoid it?

Thanks Marcus and thanks for sharing this JRL - much appreciated!
jpuziano

Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post - :-)

User avatar
JRL
Automation Wizard
Posts: 3501
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Fri May 03, 2013 7:09 pm

Oops. Got this fixed a couple hours ago but neglected to post it. Also added the ability to resize the grid object. It already had the ability to resize each column. And added sort to column one.

Still waiting for someone to make a logical reverse sort work.... Its worth 20 points.

Still don't understand where the ":-2147467259 Line 7, Column 4 " error comes from. I tried different schema.ini configurations. (Currently no schema.ini seems to be needed). And I tried different messages in the VBScript to try to understand where there was a problem. Nothing I tried made any difference. Finally I renamed the column from "Size" to "Bytes" and all is well.
jpuziano wrote:I am even more interested in the error that happens when you click on one of the two numeric columns:
Actually since I didn't parse and rearrange time and date there are actually four numeric columns and only "Size" was failing. Thus the thought "Maybe its in the name".

The other script that does this sort that I wrote for work fails to sort (with the same error) on a column named "Session". Renamed "Session" to "Terminal" and that script now sorts correctly on all columns too. Must not like leading "S"s?

Code: Select all

VBSTART
  Sub SQLToCSV(connection_string,sql_string,output_file)
    Dim outFile, objConnection, objRecordSet, strSQL, intCount
    set outFile = CreateObject("Scripting.FileSystemObject").CreateTextFile(output_file)
    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.open connection_string
    Set objRecordSet = objConnection.Execute(sql_string)
    for intcount = 0 to objRecordSet.fields.count -1
    'MsgBox (objRecordSet.fields.count)
        if intcount <> objRecordSet.fields.count-1 then
            outFile.write """" & objRecordSet.fields(intcount).name & ""","
        else
            outFile.write """" & objRecordSet.fields(intcount).name & """"
        end if
    next
    outFile.writeline ""
    do while not objRecordSet.eof
        for intcount = 0 to objRecordSet.fields.count - 1
            if intcount <> objRecordSet.fields.count - 1 then
                outFile.write """" & objRecordSet.fields(intcount).value & ""","
            else
                outFile.write """" & objRecordSet.fields(intcount).value & """"
            end if
        next
        outFile.writeline ""
        objRecordSet.movenext
    loop
    objRecordSet.Close
    set objRecordSet = Nothing
    objConnection.Close
    set objConnection = Nothing
    outFile.Close
    set outFile = Nothing
  End Sub
VBEND

Dialog>Dialog1
object Dialog1: TForm
  Left = 470
  Top = 142
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'Grid Sort Test'
  ClientHeight = 770
  ClientWidth = 550
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  Position = poScreenCenter
  ShowHint = True
  OnTaskBar = False
  DesignSize = (
    550
    770)
  PixelsPerInch = 96
  TextHeight = 13
  object MSStringGrid1: tMSStringGrid
    Left = 0
    Top = 0
    Width = 550
    Height = 770
    Anchors = [akLeft, akTop, akRight, akBottom]
    DefaultRowHeight = 18
    DrawingStyle = gdsGradient
    FixedColor = 8388863
    FixedCols = 0
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    Options = [goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goFixedColClick, goFixedRowClick, goFixedHotTrack]
    ParentFont = False
    ParentShowHint = False
    ShowHint = True
    TabOrder = 0
    ColWidths = (
      40
      200
      75
      75
      75)
  end
end
EndDialog>Dialog1

AddDialogHandler>Dialog1,MSStringGrid1,OnFixedCellClick,Sort

GetFileList>c:\*.*,vData
Separate>vData,;,vLine

Let>vDirList="Line","File","Bytes","Date","Time"%crlf%
Let>kk=0
Repeat>kk
  Add>kk,1
  Let>value=vLine_%kk%
  FileSize>value,vFileSize
  FileDate>value,vFileDate
  FileTime>value,vFileTime
  If>{%kk%<(%vLine_Count%-1)}
    ConCat>vDirList,"%kk%","%value%","%vFileSize%","%vFileDate%","%vFileTime%",%crlf%
  Else
    ConCat>vDirList,"%kk%","%value%","%vFileSize%","%vFileDate%","%vFileTime%"
  EndIf
Until>kk={%vLine_Count%-1}

DeleteFile>%temp_dir%DirList.csv

SetDialogObjectFont>Dialog1,MSStringGrid1,Arial,10,1,0
SetDialogProperty>Dialog1,MSStringGrid1,LoadFromCSV,vDirList
WriteLn>%temp_dir%DirList.csv,wres,vDirList

Show>Dialog1,res1

SRT>Sort
  DeleteFile>%temp_dir%SortedDirList.csv
  If>Sort_ACol=0
    Let>Sort_Col=Line
  EndIf
  If>Sort_ACol=1
    Let>Sort_Col=File
  EndIf
  If>Sort_ACol=2
    Let>Sort_Col=Bytes
  EndIf
  If>Sort_ACol=3
    Let>Sort_Col=Date
  EndIf
  If>Sort_ACol=4
    Let>Sort_Col=Time
  EndIf

  Let>Con=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%temp_dir%;Extended Properties='text;HDR=YES;FMT=Delimited'
  Let>SQL=SELECT * FROM DirList.csv order by %Sort_Col%
  Let>vFile=%temp_dir%SortedDirList.csv

  VBRun>SQLToCSV,con,SQL,vFile

  ReadFile>%temp_dir%SortedDirList.csv,vDirList
  SetDialogProperty>Dialog1,MSStringGrid1,LoadFromCSV,vDirList
End>Sort


User avatar
JRL
Automation Wizard
Posts: 3501
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Fri May 03, 2013 9:11 pm

jpuziano wrote:I am even more interested in the error that happens when you click on one of the two numeric columns:

---------------------------
Macro Scheduler
---------------------------
:-2147467259
Line 7, Column 4
---------------------------
OK Abort
---------------------------
Got it!

The answer is ODBC Reserved Keywords. Don't use them as column names.

User avatar
jpuziano
Automation Wizard
Posts: 1085
Joined: Sat Oct 30, 2004 12:00 am

Post by jpuziano » Fri May 03, 2013 10:19 pm

JRL wrote: The answer is ODBC Reserved Keywords. Don't use them as column names.
That is fantastic JRL, thanks! Makes sense... and for those folks who find this forum post (perhaps by searching for 2147467259)... they will find the cause of this error.

However... wouldn't it be grand if instead of just throwing...

---------------------------
Macro Scheduler
---------------------------
:-2147467259
Line 7, Column 4
---------------------------
OK Abort
---------------------------

...if Macro Scheduler could translate that into something a little bit more meaningful and add an additional line... maybe something like:

Error - ODBC Reserved Keyword "Date" cannot be used as a column name
or
Error - Improper use of ODBC Reserved Keyword: Date

Not sure if this is possible, and of course it may not always be an ODBC driver involved... but it would be a mercy to a user who otherwise might get VERY frustrated wondering why they can't sort a column named "Date" (a fairly common column name I'd think) but the others are fine.

Would this be possible Marcus?

Once again, thanks JRL... your contributions here are appreciated!
jpuziano

Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post - :-)

User avatar
JRL
Automation Wizard
Posts: 3501
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Fri May 03, 2013 10:35 pm

Did I actually say...
(Currently no schema.ini seems to be needed)
Apparently I wasn't paying attention. For the sorts to sort correctly we have to tell the sorter what the column types are and that is done with a schema.ini file. The following does (almost) everything I want it to do. Click a column once and it sorts, click it again and it reverse sorts.

I'll still give 20 points to anyone who comes up with a sorting method different than what I've used. And since I know there is always a better way to do anything, I'll give 50 points to anyone who can improve the sorting method as in making it faster or more accurate or capable of dealing with larger lists or whatever reasonable criteria you can come up with as better.

As for the ODBC reserved words... I just noticed I've used both Date and Time as column names without any failures and they are both on the reserved words list. So there must be more to this than I've been seeing. Anyone else able to shed some light on this?


Code: Select all

VBSTART
  Sub SQLToCSV(connection_string,sql_string,output_file)
    Dim outFile, objConnection, objRecordSet, strSQL, intCount
    set outFile = CreateObject("Scripting.FileSystemObject").CreateTextFile(output_file)
    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.open connection_string
    Set objRecordSet = objConnection.Execute(sql_string)
    for intcount = 0 to objRecordSet.fields.count -1
    'MsgBox (objRecordSet.fields.count)
        if intcount <> objRecordSet.fields.count-1 then
            outFile.write """" & objRecordSet.fields(intcount).name & ""","
        else
            outFile.write """" & objRecordSet.fields(intcount).name & """"
        end if
    next
    outFile.writeline ""
    do while not objRecordSet.eof
        for intcount = 0 to objRecordSet.fields.count - 1
            if intcount <> objRecordSet.fields.count - 1 then
                outFile.write """" & objRecordSet.fields(intcount).value & ""","
            else
                outFile.write """" & objRecordSet.fields(intcount).value & """"
            end if
        next
        outFile.writeline ""
        objRecordSet.movenext
    loop
    objRecordSet.Close
    set objRecordSet = Nothing
    objConnection.Close
    set objConnection = Nothing
    outFile.Close
    set outFile = Nothing
  End Sub
VBEND

IfDirExists>%temp_dir%~GridSortTest~
  DeleteFolder>%temp_dir%~GridSortTest~
EndIf
CreateDir>%temp_dir%~GridSortTest~

LabelToVar>SchemaFile,vSchemaINI
WriteLn>%temp_dir%~GridSortTest~\Schema.ini,wres,vSchemaINI

Let>LastSort=
Let>SortDirection=DESC

Dialog>Dialog1
object Dialog1: TForm
  Left = 470
  Top = 142
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'Grid Sort Test'
  ClientHeight = 770
  ClientWidth = 550
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  Position = poScreenCenter
  ShowHint = True
  OnTaskBar = False
  DesignSize = (
    550
    770)
  PixelsPerInch = 96
  TextHeight = 13
  object MSStringGrid1: tMSStringGrid
    Left = 0
    Top = 0
    Width = 550
    Height = 770
    Anchors = [akLeft, akTop, akRight, akBottom]
    DefaultRowHeight = 18
    DrawingStyle = gdsGradient
    FixedColor = 8388863
    FixedCols = 0
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    Options = [goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goFixedColClick, goFixedRowClick, goFixedHotTrack]
    ParentFont = False
    ParentShowHint = False
    ShowHint = True
    TabOrder = 0
    ColWidths = (
      40
      200
      75
      75
      75)
  end
end
EndDialog>Dialog1

AddDialogHandler>Dialog1,MSStringGrid1,OnFixedCellClick,Sort

GetFileList>c:\*.*,vData
Separate>vData,;,vLine

Let>vDirList="Line","File","Bytes","Date","Time"%crlf%
Let>kk=0
Repeat>kk
  Add>kk,1
  Let>value=vLine_%kk%
  FileSize>value,vFileSize
  FileDate>value,vFileDate
  MidStr>vFileDate,1,4,CCYY
  MidStr>vFileDate,5,2,MM
  MidStr>vFileDate,7,2,DD
  Let>vFileDate=%MM%/%DD%/%CCYY%
  FileTime>value,vFileTime
  MidStr>vFileTime,1,2,HH
  MidStr>vFileTime,3,2,MN
  MidStr>vFileTime,5,2,SS
  Let>vFileTime=%HH%:%MN%:%SS%
  If>{%kk%<(%vLine_Count%-1)}
    ConCat>vDirList,"%kk%","%value%","%vFileSize%","%vFileDate%","%vFileTime%",%crlf%
  Else
    ConCat>vDirList,"%kk%","%value%","%vFileSize%","%vFileDate%","%vFileTime%"
  EndIf
Until>kk={%vLine_Count%-1}

DeleteFile>%Temp_Dir%~GridSortTest~\DirList.csv

SetDialogObjectFont>Dialog1,MSStringGrid1,Arial,10,1,0
SetDialogProperty>Dialog1,MSStringGrid1,LoadFromCSV,vDirList
WriteLn>%Temp_Dir%~GridSortTest~\DirList.csv,wres,vDirList

Show>Dialog1,res1
DeleteFolder>%temp_dir%~GridSortTest~

SRT>Sort
  DeleteFile>%Temp_Dir%~GridSortTest~\SortedDirList.csv
  If>Sort_ACol=
    Let>Sort_Col=Line
  EndIf
  If>Sort_ACol=0
    Let>Sort_Col=Line
  EndIf
  If>Sort_ACol=1
    Let>Sort_Col=File
  EndIf
  If>Sort_ACol=2
    Let>Sort_Col=Bytes
  EndIf
  If>Sort_ACol=3
    Let>Sort_Col=Date
  EndIf
  If>Sort_ACol=4
    Let>Sort_Col=Time
  EndIf
  
  If>{(%LastSort%=%Sort_ACol%)and(%SortDirection%="ASC")}
    Let>SortDirection=DESC
  Else
    Let>SortDirection=ASC
  EndIf
  Let>LastSort=Sort_ACol

  Let>Con=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%Temp_Dir%~GridSortTest~\;Extended Properties='text;HDR=YES;FMT=Delimited'
  Let>SQL=SELECT * FROM DirList.csv order by %Sort_Col% %SortDirection%
  Let>vFile=%Temp_Dir%~GridSortTest~\SortedDirList.csv

  VBRun>SQLToCSV,con,SQL,vFile

  ReadFile>%Temp_Dir%~GridSortTest~\SortedDirList.csv,vDirList
  SetDialogProperty>Dialog1,MSStringGrid1,LoadFromCSV,vDirList
End>Sort

/*
SchemaFile:
[DirList.csv]
Col1="Line" Integer
Col2="File" Text
Col3="Bytes" Integer
Col4="Date" DateTime
Col5="Time" DateTime
*/

Post Reply
cron
Sign up to our newsletter for free automation tips, tricks & discounts